Draven Draven - 3 months ago 15
MySQL Question

Laravel not updating db record (Model->$exists false)

I am trying to update my "Trip Name" (

name
field in the
user_trips
table).

I followed the "Laravel From Scratch: Updating Records and Eager Loading" video but it doesn't update, but I do get redirected back and get the session
msg
"Your trip has been renamed". The only difference I can see is that I am using one page (not an /edit page).

The problem is that the
$exists
variable in Laravels Model.php class is
false
so it's returning
false
in the
update()
method.

Why is
$exists
false?

routes.php

<?php

Route::get('/', 'TripBuilderController@index');

Route::post('add_flight', 'FlightController@store');

Route::patch('trip/{trip}', 'TripBuilderController@update');


TripBuilderController

<?php
namespace App\Http\Controllers;

use App\Airport;
use App\UserTrips;
use Illuminate\Http\Request;

/**
* Class TripBuilderController
*
* @package App\Http\Controllers
*/
class TripBuilderController extends Controller
{
/**
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function index()
{
$airports=Airport::all();
$user_trips=UserTrips::whereUserId(1)->with('userflights.flightfrom', 'userflights.flightto')->get();

return view('welcome', compact('airports', 'user_trips'));
}

/**
* @param Request $request
* @param UserTrips $user_trips_obj
*/
public function update(Request $request, UserTrips $user_trips_obj)
{
# Returns {"_token":"RANDOM TOKEN","_method":"PATCH","name":"New Trip Name"}
//return $request->all();

$user_trips_obj->update($request->all());
# Returns []
//return $user_trips_obj;

# Results below.
//dd($user_trips_obj);

return back()->with('msg', 'Your trip has been renamed');
}
}


UserTrips Model

<?php
namespace App;

use Illuminate\Database\Eloquent\Model;

/**
* Class UserTrips
*
*/
class UserTrips extends Model
{
/**
* Indicates if the model should be timestamped.
*
* @var bool
*/
public $timestamps=FALSE;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable=[
'name',
'user_id'
];

/**
* @param UserFlights $user_flights_obj
* @return Model
*/
public function addFlight(UserFlights $user_flights_obj)
{
return $this->userflights()->save($user_flights_obj);
}

/**
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function userflights()
{
return $this->hasMany(UserFlights::class);
}

/**
* @return mixed
*/
public function addTrip()
{
# Retrieve the trip by the attributes, or instantiate a new instance...
$trip_obj=$this->firstOrNew(['user_id'=>1]);
if(!$trip_obj->id)
{
$trip_obj->name='My Trip';
$trip_obj->save();
}

return $trip_obj;
}
}


welcome.blade.php

@extends('layouts.master')

@section('title', 'Trip Builder')

@section('content')
<div id="airport_form">
<form method="POST" action="/add_flight">
{{ csrf_field() }}
<div class="form-group">
<select class="form-control" name="flight_from">
@foreach($airports as $airport)
<option value="{{ $airport->id }}">{{ $airport->name }}</option>
@endforeach
</select>
</div>
<div class="form-group">
<select class="form-control" name="flight_to">
@foreach($airports as $airport)
<option value="{{ $airport->id }}">{{ $airport->name }}</option>
@endforeach
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Add Flight</button>
</div>
</form>
</div>
<div id="trip_info">
<div id="trip_form">
<form method="POST" action="/trip/{{ $user_trips[0]->id }}">
{{ csrf_field() }}
{{ method_field('PATCH') }}
<label for="trip_name">Trip Name:</label> <input type="text" name="name" id="trip_name" class="form-control" value="{{ $user_trips[0]->name }}"><button type="submit" class="btn btn-primary">Rename Trip</button>
</form>
</div>
<div id="flight_info">
<table class="table table-striped table-bordered table-hover">
<tr>
<th>
From
</th>
<th>
To
</th>
<th>
Options
</th>
</tr>
@foreach($user_trips[0]->userflights as $user_flight)
<tr>
<td>
{{ $user_flight->flightfrom->name }}
</td>
<td>
{{ $user_flight->flightto->name }}
</td>
<td>
<a href="#">Remove</a>
</td>
</tr>
@endforeach
</table>
</div>
</div>
@stop


dd($user_trips_obj); results

UserTrips {#156 ▼
+timestamps: false
#fillable: array:2 [▼
0 => "name"
1 => "user_id"
]
#connection: null
#table: null
#primaryKey: "id"
#keyType: "int"
#perPage: 15
+incrementing: true
#attributes: []
#original: []
#relations: []
#hidden: []
#visible: []
#appends: []
#guarded: array:1 [▼
0 => "*"
]
#dates: []
#dateFormat: null
#casts: []
#touches: []
#observables: []
#with: []
#morphClass: null
+exists: false
+wasRecentlyCreated: false
}

Answer

One problem I see is that the Laravel's Route Model Binding will not work correctly since you've named the model trip in routes.php. However, in your TripBuilderController class, you've named it $user_trips_obj. It should be renamed to trip or you'll need to explicitly redefine it in routes.php.

So, this

public function update(Request $request, UserTrips $user_trips_obj)

Should be

public function update(Request $request, UserTrips $trip)

because you've defined the trip parameter as trip in routes.php

Route::patch('trip/{trip}', 'TripBuilderController@update');

See Route Model Binding- Laravel Documentation