Suppose I have a Conversation
model like this :
class Conversation extends Model
{
public function questions (){
return $this->hasMany('App\Question','conversation_id','conversation_id');
}
public function category ()
{
return $this->belongsTo('App\Category', 'cat', 'cat_id');
}
}
And a Question
model like this:
class Question extends Model
{
public function conversation ()
{
return $this->belongsTo('App\Conversation', 'conversation_id', 'conversation_id');
}
}
As you can see there is a hasMany
relation between those two.
In the other hand there is a Category
like below that has a relation with Conversation
model :
class Category extends Node
{
public function conversations (){
return $this->hasMany('App\Conversation','cat','cat_id');
}
}
Now I want to append an attribute named question_count
to Category
that counts all questions of conversations of each category. for that I added this :
public function getQuestionsCountAttribute ()
{
return $this->conversations->questions->count();
}
But when fetch a category I got this error :
ErrorException in Category.php line 59:
Undefined property: Illuminate\Database\Eloquent\Collection::$questions
What did I do? how can I count relations of a relation with minimum server overloading?
I am using laravel 5.3.4.
I think that you need a has many through relationship here.
What you do wrong:
When you write
$this->conversations->questions
, this can't work, because thequestions
are a relation of a single conversation and not of a collection of conversations (here,$this->conversations
is a Collection)The solution:
Using hasManyThrough relation:
You can find the documentation for this relation on this page, if my explanation is bad
The basics are, you need to define a relation on your
Category
model:(I will let your look into the documentation for your non standards foreign keys)
You should then be able to use:
$category->questions->count()
$this->conversations contains the collection of conversations. Each of the conversations has its own questions property that contains all related questions for that conversation, however there is no questions attribute on the collection itself that would contain all related questions for that category.
In order to be able to get the count of all the questions in the category, you need to define a hasManyThrough relation that would link questions to the category directly.
First, add the relation to your Category model:
Once you have it, you'll be able to get the count of all questions for a category with:
You can count related model with 'withCount' method. https://laravel.com/docs/5.3/eloquent-relationships#counting-related-models