laravel relations error Trying to get property of non-object - laravel-5

I'm trying to retrieve data from two tables and in order using a hasMany relationship. i.e
Public childModel (){
return $this->hasMany(childModel);
}
In the view when I run the foreach loop:
foreach($parentModel as $parentModel)
or
foreach($parentModel->childModel as $childModel)
then
{{parentModel->childModel}}
I get json printed on my screen just fine (including the column I want to output.)
When I try
`{{parentModel->childModel->column}}`
I get "Trying to get property of non-object"

Figured it out. I was making a 'where' statments when i initialized the parentModel variable, that 'where' statement rejected the table in the childModel. Only found out after running tests.

Related

Why does groupBy() work but Count() does not in laravel eloquent model function?

I need to get counts of all the records based on belongsToMany relationship. normally I can use groupBy() in a function inside the model. but if I use count() or withCount() inside a model function, i get the error as followed:
function code:
public function TaskCount(){
return $this->belongsToMany(User::class)->count();
}
Error message:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to a member function addEagerConstraints() on int in file /Users/dragonar/Dev/iyw/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php on line 560
If I do the following...
public function TaskCount(){
return $this->belongsToMany(User::class)->Count();
}
//expected record is 4(int)
//output is 4(array) user records.
...it gives me data but like 4 records of the user instead of a number 4. The user data is useless. The only thing needed is totalCount for those records.
Relationship methods have to return Relation type objects. You are returning the result of a query, count() returns a number not the Relation object / Builder. Remove the count from that statement you are returning. Renamed the relationship tasks here.
public function tasks()
{
return $this->belongsToMany(User::class);
// this returns a Relation type object a BelongsToMany object
}
Where you need to use that relationship you can then use count:
$something->tasks()->count();
Or you can load the count of the relationship using loadCount:
$something->loadCount('tasks');
$something->tasks_count;
Or via eager loading for a collection:
$results = Something::withCount('tasks')->get();
foreach ($results as $model) {
echo $model->tasks_count;
}
If you really wanted to you could create an accessor to get the count as well, you just may want to avoid the N+1 issue by preloading the relationship and using the dynamic property to access it in the accessor.
These relation objects are Builders. When you called groupBy on it previously that is returning the Builder, it isn't executing the query. You can add where conditions and order by statements because they are just building the query, not executing it, they return the builder you are calling the method on.
Laravel 6.x Docs - Eloquent - Relationships - Counting Related Models withCount loadCount
Why not use: Task::all()->count(); ?
you can use the withCount method while calling relation like this
User::withCount('images')->get();
You can add get the data and just count it.
public function TaskCount(){
return $this->belongsToMany(User::class)->get()->count();
}
You can call it like
$taskCount = $task->TaskCount();

Pagination of the results is not working as expected

I am using paginate() inside the controller and passing the results to view.
I have 10 results.
If I pass paginate(3 or some number higher) dd() function is giving me
html "" empty string
If I pass paginate(2) I have some results
When I pass those results to the view I have an error
::name {{$name->links()}} is not recognized
I am puzzled here. Have no idea what to do
My paginate is working normally on my previous view.
My controller
public function tagnews($team_id) {
$teamNews = Team::with('news')->find($team_id)->paginate(5);
return view ('news.tag_news', compact('teamNews'));
}
in the view file I have
{{ $teamNews->links() }}
Models are connected with pivot table
They have BelongsToMany relationship Team and News
Without the pagination everything works as expected.
When I include pagination I have all these mentioned problems

Laravel Eager-loading works only when calling attribute

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;

How to get all records which meet a Criteria in Laravel Tinker?

I can get the first user, who is an admin in Laravel's tinker using the following command:
$adminUser = App\User::where('is_admin',true)->first();
How do I get all the users which meet this where criteria?
Just change first() to get().
$adminUser = App\User::where('is_admin',true)->get();
first() is used when you want to retrieve single row or column. where get() is used to retrieve all rows.
just go through the laravel official documentation database query builder section here. It will give you information regarding most of every possible things you can playoff with laravel.
$users = App\User::where("is_admin", true)->get();
The get method returns an Illuminate\Support\Collection containing the results where each result is an instance of the PHP StdClass object. You may access each column's value by accessing the column as a property of the object:
foreach ($users as $user) {
echo $user->name;
}
Src: https://laravel.com/docs/5.6/queries
In case of Tinker, things in Query builder and Eloquent docs will work in Tinker. It exists for the purpose of instantly getting the result without debugging using your real application.
The first() function is used when you want to retrieve single row, whereas the get() function is used to retrieve all matching rows.
$adminUser = App\User::where('is_admin', true)->get();
dd($adminUser);

Relation multiple Models

long time i been not working with laravel, im strugling in getting some data.
Im trying to get all the bookmakers from a competition but is not getting:
db:
leagues:
-id
-name
league_bookmakers:
- id
- league_id
- bookmaker_id
bookmakers:
- id
- name
controller:
$example = \App\League::find(440);
dd($example->bookmakers());
Model League:
public function bookmakers()
{
return $this->hasMany(LeagueBookmaker::class);
}
When you call a relation method on a model ($example->bookmakers()), it returns the actual relation, allowing you to add additional constraints.
What you need to be calling is the 'dynamic property', which simply returns the data from the relation as-is:
$example->bookmakers // without the ()
What are you getting? Are you getting an empty collection?
As commented try doing this
dd($example->bookmakers);
Also, try doing dd($example) first and see if it has the bookmakers collection property in it.
When you make relation with league_bookmakers table, you will not get bookmakers data directly. In that case, you can define a belongsToMany Relation like below code -
public function bookmakers()
{
return $this->belongsToMany(Bookmaker::class, 'league_bookmakers','league_id', 'bookmaker_id');
}
It will return bookakers table info directly.

Resources