Laravel 5.2 form model binding - displaying model with() empty relationship - laravel

SOLVED, something else was causing the error, not an empty relationship.
I am having some trouble making this work. I have a large form that is combining 4 tables. For my example I will just use 3. Here is what I send to the view:
$student = Student::with('primaryInsurance')->with('secondaryInsurance')->findOrFail($student_id);
The form works fine if the student has both primaryInsurance and secondaryInsurance but I get a "Trying to get property of non-object" if one or both are not in the table. How can I avoid this?
Here are a couple fields from my form:
{{ Form::text('last_name', null, ['class' => 'form-control required']) }}
{{ Form::text('primaryInsurance[insured_name]', null, ['class' => 'form-control']) }}
{{ Form::text('secondaryInsurance[insured_name]', null, ['class' => 'form-control']) }}
From the student model:
public function primaryInsurance() {
return $this->hasOne(StudentInsurance::class, 'student_id', 'student_id')->where('is_primary', '=', 1);
}
public function SecondaryInsurance() {
return $this->hasOne(StudentInsurance::class, 'student_id', 'student_id')->where('is_primary', '=', 1);
}

First, combine your with query to make your code cleaner. Like so:
$student = Student::with('primaryInsurance', 'secondaryInsurance')->findOrFail($student_id);
Next, in your view check that the object is set (I think you should be using an object here versus array - that's what's causing the error I believe). You'll have to test. Your issue can also be that you're wrapping the object in ' '. Don't. I'd need to see your controller logic to get a better sense if this doesn't work.
{{ Form::text($primaryInsurance->insured_name, null, ['class' => 'form-control']) }}
You can also do a ternary on this as well to default to null if doesn't exist:
{{ Form::text((($primaryInsurance->insured_name) ?: null), null, ['class' => 'form-control']) }}

Related

laravel prefil form inputs from controller

Hi I'm using laravel forms.
{!! Form::text('product_name', null, array('class' => 'form-control date_pick')) !!}
Is there a way to set this default input from controller?. Think we can do it with Flash but I couldn't find an example. I want to take vlues from a model and prepopulate.
$products = Products::all();
It would be great if someone know how to do this. What is the easiest way to do it?
This is done with a basic edit route where you simply use:
In ModelController you would call the edit page:
public function edit(ModelName $model) {
return view('name.of.the.blade.view', compact('model')); // if using compact then without dollar symbol
}
In blade view simply make the form with all the input fields you have for that model:
{!! Form::model($model, ['method' => 'PATCH', 'route' => ['model.update', $model->id],]) !!}
Now all the form fields will have the values from that model.
{!! Form::close() !!}
And the edit and update route (inside routes/web.php) would be like this:
Route::get('/model/{model}/edit', 'ModelController#edit')->name('model.edit');
Route::patch('/model/{model}', 'ModelController#update')->name('model.update');

display fetch data in dropdown menu with "where" value selected in laravel

I am trying to display the currencies in the dropdown menu but I need the data with a value of default=1 to be selected. upon searching, i found a sample and tried to applied it to my controller, here's what I came up,
$currencies = \DB::table('currencies')->where('default', 1)->lists('acronym');
it doesn't work. the error message said
Call to undefined method Illuminate\Database\Query\Builder::lists()
also I read a comment that the list() is already obsolete in laravel.
how can I achieve this?
here's from my create function in controller
public function create()
{
$currencies = \DB::table('currencies')->where('default', 1)->lists('acronym');
return view ('orders.create')->with('currencies', $currencies);
}
here's from create blade
{{ Form::select('currency_id', $currencies, Input::old('currency_id'),null, ['class' => 'form-control input-lg','required']) }}
thank you so much in advance!
Try using ->pluck(),
$currencies = \DB::table('currencies')->pluck('currency_name','id');
// In blade
{{ Form::select('currency_id', $currencies, null, ['class' => 'form-control input-lg','required']) }}
Read more about pluck here.

Laravel 5.5 - Missing required parameters for [Route:]

What I'm trying to achieve is very simple, but I'm just making this a lot harder than it needs to be. So am seeking help for what is apparently, my lack of Laravel experience.
All I want to do is have a form that can update database entries via a text input. This has to be dynamic as it's being used for a few databases and I don't want to have multiple files for them.
Sorry in advance for the probable messy/crap code...
Here's the routes I have:
Route::get('/server/{server}/players/{playerID}/greeting', 'PlayerProfileController#greeting');
Route::post('/server/{server}/players/{playerID}/greeting', 'PlayerProfileController#updateGreeting')->name('greeting.update');
The PlayerProfileController
// Display greeting message
public function greeting($server, $playerID) {
$greetInfo = DB::connection($server)
->table('clients')
->where('id', $playerID)
->first();
return view('servers.greeting')
->with('greetInfo', $greetInfo);
}
// Update greeting message
public function updateGreeting(Request $request, $server, $playerID) {
$gUpdate = DB::connection($server)
->table('clients')
->where('id', $playerID)
->update(['greeting' => $request->input('greet')]);
return back()->with('success', 'Greeting updated successfully!');
}
And finally the form
{{ Form::open(['action' => ['PlayerProfileController#updateGreeting', $greetInfo->greeting], 'method' => 'POST']) }}
{{ Form::bsText('greet', '', ['placeholder' => 'Update greeting or leave blank to remove current message']) }}
{{ Form::hidden('_method', 'PUT') }}
<br>
{{ Form::bsSubmit('Update',['class' => 'btn btn-outline-secondary']) }}
{!! Form::close() !!}
Any and all help is appreciated. Thank you in advace.
The ErrorException you're seeing is caused by the missing argument for the route you're trying to call. Your route is expecting server and playerId, wheres you're only sending it $greetInfo->greeting.
As you're using named route, my suggestion would be to use route() helper like so:
Route::get('/server/{server}/players/{playerID}/greeting', 'PlayerProfileController#greeting');
Route::post('/server/{server}/players/{playerID}/greeting', 'PlayerProfileController#updateGreeting')
->name('greeting.update');
class PlayerProfileController extends Controller {
public function greeting($server, $playerID) {
$greetInfo = DB::connection($server)
->table('clients')
->where('id', $playerID)
->first();
return view('servers.greeting')
->with('greetInfo', $greetInfo);
}
// Update greeting message
public function updateGreeting(Request $request, $server, $playerID) {
$gUpdate = DB::connection($server)
->table('clients')
->where('id', $playerID)
->update(['greeting' => $request->input('greet')]);
return back()->with('success', 'Greeting updated successfully!');
}
}
{{ Form::open(['action' => route('greeting.update', [$server, $playerId]), 'method' => 'post']) }}
{{ Form::bsText('greet', '', ['placeholder' => 'Update greeting or leave blank to remove current message']) }}
{{ Form::bsSubmit('Update',['class' => 'btn btn-outline-secondary']) }}
{!! Form::close() !!}
Please replace $server and $playerId variables with the ones representing the arguments you want to send with the request.
You can see I've also removed {{ Form::hidden('_method', 'PUT') }}, as this was trying to overwrite the post method on the Form::open method.

Laravel use all Entries from DB in Select Box

YOu can create a select Box like this:
{{ Form::select('age', ['Under 18', '19 to 30', 'Over 30']) }}
Lets say I want to have a select box of all my users (saved in the DB). How can I do that? I've got a User-Model.
In your controller
use App\Entities\User;
public function getUsers(User $user)
{
$allUsers = $user->lists('name', 'id');
return view('users.view',compact('allUsers'));
}
In your blade
{!! Form::select('users[]', $allUsers,null , ['multiple'=>'multiple', 'class' => 'form-control']) !!}

Laravel 5 Relationship Not Working?

In my app I have few models: User and Profile. The User model is only for companies, my app is for companies only. When a user registers, they only fill in their name, email address and password. My Profile model has columns for company name, address etc. My profile form does not work; not saving to the database. Here is the setup:
Controller for the form:
public function update($company_name)
{
$user = User::whereCompanyName($company_name)->firstOrFail();
$user->fill(Input::all());
$user->save();
flash('You have successfully edited your profile');
return redirect('/');
}
User.php:
public function profile()
{
return $this->hasOne('Profile');
}
Profile.php:
protected $fillable = ['company_name', 'company_logo', 'company_founded'];
public function user()
{
return $this->belongsTo('App\User', 'user_id','ID');
}
The Form:
{!! Form::model($user, array('method' => 'PATCH', 'route' => array('profile.update', $user->company_name), 'files' => true)) !!}
{!! Form::hidden('user_id', Auth::user()->id) !!}
// more fields
<div class="form-group">
{!! Form::label('company_name', 'Company Name') !!}
{!! Form::text('company_name', null, ['class' => 'form-control']) !!}
</div>
{!! Form::submit('Update Profile', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}
Have I set the relationship correct? Nothing is saving to the database.
You’re updating the user model and the user model only. You need to also set the attributes in the profile relation:
$user->update(Input::all());
$user->profile->update(Input::all());
Your controller action could also be tidied up a bit, by using route–model binding to inject your User model instance, and also use the service container to provide a Request instance too so you’re not using the Input façade:
public function update(User $user, Request $request)
{
$user->update($request->all());
$user->profile->update($request->all());
flash('You have successfully updated your profile.');
return redirect('/');
}
I want to comment but do not have enough reputation :( A few days ago I found a little problem with this approach:
$user->update(Input::all());
$user->profile->update(Input::all());
In this case the mutators in related model (profile in the example) like this are not invoked (may be a bug):
public function setLoremIpsumAttribute($attr)
{
# code
}
In controller I tried another approach and it worked:
$user->update($request->all());
$user->profile->fill($request->all()['profile'])->push();
In Laravel 5 when you want to chain with relation, you need for exemple (Post with comment related) use the method from your comment.
Post::find(id)->comment()->where(your where statement)
Docs from Laravel:
If you need to add further constraints to which comments are retrieved, you may call the comments method and continue chaining conditions:
$comments = Post::find(1)->comments()->where('title', '=', 'foo')->first();

Resources