0

Using the Laravel Eloquent ORM system I have created the following models:

/**
 * @property int $id
 */
class Category extends Model
{
    public function questions()
    {
        return $this->hasMany(Question::class);
    }
}

/**
 * @property int $id
 * @property int $category_id
 */
class Question extends Model
{
    public function answers()
    {
        return $this->hasMany(Answer::class);
    }
}

/**
 * @property int $id
 * @property int $question_id
 */
class Answer extends Model {}

Now I am trying to eager load the following values:

  1. All categories
  2. The amount of questions per category
  3. The amount of answered questions per category

I have solved both 1 and 2 using this code:

$categories = Category
    ::withCount('questions')
    ->get();

$vars = ['categories' => $categories];

For the third value I tried something like this (which does not work):

$categories = Category
    ::withCount(['questions', 'questions as answered_questions' => function ($query) {
        $query->select()
            ->from('answers')
            ->whereRaw('answers.question_id = questions.id');
    }])
    ->get();

How can I efficiently calculate the amount of questions having one or more answers?

Duncan Lukkenaer
  • 12,050
  • 13
  • 64
  • 97
  • this may help you https://stackoverflow.com/questions/39633691/laravel-5-3-withcount-nested-relation – rkj Jun 26 '18 at 11:21
  • @rkj Thanks for the suggestion, but it does not solve my problem. With the solution given there I could count the *amount of answers* instead of the *amount of questions with answers*. – Duncan Lukkenaer Jun 26 '18 at 11:28
  • what do you mean by amount of questions with answers ? you mean amount of questions that has at least one answer ? – rkj Jun 26 '18 at 11:31
  • @rkj Exactly, that's what I'm looking for – Duncan Lukkenaer Jun 26 '18 at 11:31

2 Answers2

1

you can try has

Category Model

class Category extends Model
{
    public function questions()
    {
        return $this->hasMany(Question::class);
    }

    function answers()
    {
      return $this->hasManyThrough(Answer::class, Question::class);
    }
}

Fetch data

$categories = Category::withCount('questions')->has('answers')->get();

foreach($categories as $category){
  $category->name." - ". $category->questions_count;
}

Here questions_count is total question that has at least one answer for that category

rkj
  • 8,067
  • 2
  • 27
  • 33
1

With the help of @rkj I found out about the has function. With that I was able to create the following solution:

$categories = Category
    ::withCount(['questions', 'questions as answered_questions' => function ($query) {
        $query->has('answers');
    }])
    ->get();

Now the $category->questions_count and $category->answered_questions are available to me, which is exactly what I need.

Duncan Lukkenaer
  • 12,050
  • 13
  • 64
  • 97