1

I'm developing a simple survey system, and I'm having problem with getting the right data.

I'm trying to retrieve all categories with questions and answers, that are assigned to a specific survey.

ERD:

The following code nearly works, however it does not filter the questions that are assigned to a specific survey.

$categories = Category::whereHas('questions.surveys', function ($query) use ($id) {
    $query->where('surveys.id', $id); 
})->with('questions', 'questions.answers', 'questions.surveys')
->get();

Question Model:

class Question extends Model
{
    public function answers() 
    {
        return $this->belongsToMany('App\Models\Surveys\Answer', 'question_answers');
    }

    public function category() 
    {
        return $this->belongsTo('App\Models\Surveys\Category');
    }

    public function surveys() 
    {
        return $this->belongsToMany('App\Models\Surveys\Survey', 'survey_questions');
    }
}

Category Model:

class Category extends Model
{
    public function questions() 
    {
        return $this->hasMany('App\Models\Surveys\Question');
    }
}

Survey Model

class Survey extends Model
{
    public function questions() 
    {
        return $this->belongsToMany('App\Models\Surveys\Question', 'survey_questions');
    }
}
Rwd
  • 34,180
  • 6
  • 64
  • 78
AndyD
  • 13
  • 2
  • Can you log the query to see what happens? https://stackoverflow.com/questions/41140975/laravel-eloquent-display-query-log/41141045 – mrhn May 02 '19 at 11:34
  • I would suggest you look to install Laravel Debug Toolbar (https://github.com/barryvdh/laravel-debugbar) as it will show you the RAW sql query that ran. This may well be able to help you narrow down on the issue. However, I think the issue is to do with whereHas('questions.surveys'). This argument should be a model function if I'm not wrong. so should be 'questions' and then you put the where on $query->surveys()->where('surveys.id', $id); – Petay87 May 02 '19 at 11:35

1 Answers1

1

For this you need to constrain your eager loads as well:

$categories = Category::with([
    'questions' => function ($query) use ($id) {
        $query->with('answers', 'surveys')
            ->whereHas('surveys', function ($query) use ($id) {
                $query->where('id', $id);
            });
    },
])->whereHas('questions.surveys', function ($query) use ($id) {
    $query->where('id', $id);
})->get();

This way you're saying only get you the categories that are related to a specific survey and only get the question that relate to that category and the specific survey.

Rwd
  • 34,180
  • 6
  • 64
  • 78