i'm having a real weird problem in accessing eloquent relation in laravel 7
i use the "has-one" eloquent relationship
when i dump the data it returns like this
this shows the object with it's relations
when i try access the relations through $subject->description
it returns null like this
returns null on accessing the relation
it's weird and first time it happens to me
you can user foreach in blade example
#foreach($subject->description as $description)
{{ $description->id }}
{{ $description->subject_id }}
...
#endforeach
or in the controller
foreach($subject->description as $description){
$description->id;
$description->subject_id;
}
I think you can try if you use "belongs to" then you can access data without looping .
Related
I have 2 tables and I need to show the latest single data from row based based on due_date field in my blade file.
blade
#foreach(Auth::user()->statements->orderBy('due_date','desc')->get() as
$statement)
<p> Your unpaid bill is: {{ $statement->billamount }} </p>
#endforeach
I get this error
Method Illuminate\Database\Eloquent\Collection::orderBy does not exist.
(View:...\home.blade.php)
EDIT
I edited the code based on the comments below:
#foreach(Auth::user()->statements()->latest('due_date')->first() as
$statement)
{{ $statement->billamount }} //I only need the latest record to be shown
#endforeach
and it throws this error:
Trying to get property 'billamount' of non-object.
change Auth::user()->statements to Auth::user()->statements()
orderBy is a method of Query Builder. Auth::user()->statements is a collection and Auth::user()->statements is a query builder
to show latest row data only you can use orderBy and first method. example:
Auth::user()->statements()->orderBy('created_at','desc')->first()
another way use latest method:
Auth::user()->statements()->latest('created_at')->first()
#foreach(Auth::user()->statements()->latest('due_date')->first()) as
$statement)
when you look closely there is an extra bracket after first() so remove it and test it
#foreach(Auth::user()->statements()->latest('due_date')->first() as
$statement)
like above
also when using first you dont need to give foreach use get() rather than first()
get() return s a collection while first() returns a single record details
I trying to learn laravel and to do some tests/demo apps. I've struggling now with laravel/eloquent tables relations. And I need advice.
I have 3 models [Application, Term, AppState] and their tables applications[id, terms_id, appStates_id, and other cols ], terms[id, startDate, endDate, ...], app_states[id, caption]
Application.php
public function term()
{
return $this->belongsTo('App\Term');
}
public function appState()
{
return $this->belongsTo('App\AppState');
}
in Term.php and AppState.php i have:
public function applications()
{
return $this->hasMany('App\Application');
}
How I can get let's say "caption"/"startDay"+"endDate" in blade for each application? I can get their ids $app->terms_id/$app->appStates_id in foreach loop, but i want get caption value from app_states table.
Has to be this relations also specified in migrations? In some tuts is mentioned, that is not needed in case i want to handle it only in laravel.
Thanks for advice
You can access a model's relationship values by calling the relationship method like a property.
$application = Application::find(1);
$application->term->startDate;
$application->term->endDate;
$application->appState->caption;
Also your relationship with AppState is wrong, since your foreign key doesn't follow a snake_case typing, you'll need to provide the appropriate key for it
public function appState()
{
return $this->belongsTo('App\AppState', 'appStates_id');
}
You might also want to check terms_id as well since the model name (Term) is singular but the foreign key is plural.
Has to be this relations also specified in migrations? In some tuts is mentioned, that is not needed in case i want to handle it only in laravel.
Well, yes, you don't need to if Laravel will only be the one accessing that database. But if any cases in the near future you decide to migrate to a different framework or use the same database in another application, it's better to include these relationships in the migration. Also a database administrator would probably cringe if you don't.
So provided your relationships are correctly setup, you can access them anywhere you have an instance of that model.
So for example, lets say you have passed a collection of applications to your view ($apps):
#foreach($apps as $app)
{{ $app->term->startDate }}
{{ $app->term->endDate }}
{{ $app->appState->caption }}
#endforeach
Important Note: We are accessing the Eloquent relationship using ->appState rather than ->appState(). The later is actually accessing a Query Builder instance and has some more advanced use cases
I've defined my Slot model to load the relations from User model like so :
public function userAssignedFull(): HasOne {
return $this->hasOne(User::class,'id','user_assigned');
}
('slots' table contains 'user_assigned' field by which I connect to User records on 'id')
The following code finds Slot model but without 'userAssignedFull'. I get only the user ID in 'user_assigned'.
$slot = Slot::with('userAssignedFull')->find($slot_id);
But calling this afterward returns me the wanted relation:
$fullUserModel = $slot->userAssignedFull;
Can anyone tell me what am I doing wrong ?
Builder::with() returns the Builder instance.
So you have to call $slot->userAssignedFull; to get the collection of data.
From the docs:
When accessing Eloquent relationships as properties, the relationship
data is "lazy loaded". This means the relationship data is not
actually loaded until you first access the property.
And this $slot->userAssignedFull; is your "first access the property".
Try this
$slot = Slot::where('id', $slot_id)->with('userAssignedFull')->first();
$slot->userAssignedFull;
I'm starting to learn about Laravel Framework and I have a little doubt.
I have 2 models: Customers and Opportunities.
I want to display on opportunities/show.blade.php the customer name but I have a problem with the format of the data I retrieve from customer table on the controller.
I have this show function on my OpportunityController:
public function show($id)
{
$opportunity = Opportunity::find($id);
$customerName = Customer::select('name')->where('id','=',$opportunity->customer_id)->first();
return view('opportunities.show',compact('opportunity','customerName'));
}
And i call this variable on the show.blade.php like this:
{{ $customerName }}
But it's showing the customer name on this format:
Customer: {"name":"John"}
How can I show the customer name as this:
Customer: John
Thank you!
The data return by a model is a Std Class Object, so you can use it like:
{{ $customerName->name }} // i.e. variable->column_name
It will print John.
If the you are using get() instead of first() then you have to iterate the returned array of Std Class Object variable by using foreach() loop.
You are currently returning a Model Object. So, you have to specify the attribute you wish to display. In your case, you selected only the name. So, do this:
{{ $customerName->name }}
The following query selects a single row from the database, but it is still returned as an object:
Customer::select('name')->where('id','=',$opportunity->customer_id)->first();
So the result of the query will be an object that translates to {"name":"John"}
If you want the name value you can either use {{ $customerName->name }} in your view or change the query to the following to get only the name column:
Customer::select('name')->where('id','=',$opportunity->customer_id)->first()->name;
$customerName is treated as an object in this case so please try {{ $customerName->name }} for getting a value of name .
Hope it can help you
I have created a model relationship between 3 different tables/models.
Since I get a collection of objects due to hasMany-property I have to use a for-loop to access each of the Models methods in order to get the data I want.
Is there anyway to tell that I want it to run the same function on all the objects?
Pseudo code:
Model A //HasMany Model B
Model B //HasMany Model C, Belongs to A
Model C //BelongsTo C
$foo = new User::Find(Auth::id());
//Need to loop the collection of data in order to get the information
foreach($foo->permissions as $permission)
{
$name = $permission->permissionsTypes->name;
}
I have tried to do this:
$foo->permissions->permissionsTypes;
But since it is a collection it does not work.
Is there any other way to get this information without looping through the array?
Thanks for any guidance!
Use pluck() and collapse():
$permissionsTypes = $foo->permissions->pluck('permissionsTypes')->collapse();
Might be you have defined the hasMany relationship if yes then please change hasMany into hasOne then
foreach($foo->permissions as $permission)
{
$name = $permission->permissionsTypes->name;
}
Or you could just get one of objects by it's index:
{{ $permission[0]->name}}
Or get first object from collection:
{{ $permission->first() }}
When you're using find() or first() you get an object, so you can get properties with simple:
{{ $object->name}}