magmatic's avatar

"With" or "load" a sub-relation ignores the filter

Am I doing something wrong, or does loading a subrelation ignore the filter?

$level->load([
	"readableLessons.progresses" => function ($query) {
		$query->where("state", "completed");
	},
]);

When I count the items in $level->readableLessons->first()->progresses->first()->count(), I get the wrong number, because it isn't filtering out only the ones that are completed.

Any comments please?

0 likes
9 replies
Glukinho's avatar

Is it right that you use count() on a model (returned by first()) and not on a collection?

Maybe this would give you proper result?

$level->readableLessons->first()->progresses->count()
magmatic's avatar

@Glukinho Ah yes, you are correct of course. Now that I look at it again, that is actually what I'm doing. Well, I'm first looping over readable lessons and counting up the count() of each progress. But thanks!

Glukinho's avatar

Or this?

$level->load([
            'readableLessons' => function ($query) {
                $query->whereRelation('progresses', 'state', '=', 'completed');
            }
        ]);
magmatic's avatar

@Glukinho Thanks. I tried this, but it also doesn't give the result I'm looking for. But thanks for the suggestion.

Glukinho's avatar

@magmatic I have very similar models/relations structure in my app (Project - Person - OnlineMeeting vs your Level - ReadableLesson - Progress) and this construction gave me proper result: loaded relationship $project->persons has only persons with filtered onlineMeetings. My code is:

$project = Project::find(10);

$project->load([
	'persons' => function ($query) {
		$query->whereRelation('onlineMeetings', 'id', '=', 4);
	}
]);

dd($project->persons->first()->onlineMeetings); // project has only one person which has online meeting with id = 4
magmatic's avatar

@Glukinho Yeah, I think that's exactly what I'm doing. It should work. In fact, I just figured out what I was doing wrong. I'll make another post describing it.

magmatic's avatar
magmatic
OP
Best Answer
Level 1

Thank you everyone for your ideas. I found out what I was doing wrong. It turns out my code as originally posted would have worked correctly, but that's not exactly what I was doing. I was also calling "load" a second time to load another relation "readableLessons.translations". It turns out if I call "load" twice, the second call somehow deletes the first one. The following code doesn't work.

$level->load("readableLessons");

$level->load([
	"readableLessons.progresses" => function ($query) {
		$query->where("user_id", Auth::id())->where("state", "completed");
	},
]);

$level->load([
	"readableLessons.translations" => function ($query) {
		$query->where("language_id", session("languageId", "en_CA"));
	},
]);

This code does work:

$level->load([
	"readableLessons",

	"readableLessons.progresses" => function ($query) {
		$query->where("user_id", Auth::id())->where("state", "completed");
	},

	"readableLessons.translations" => function ($query) {
		$query->where("language_id", session("languageId", "en_CA"));
	},
]);

I'm no expert, but I might be tempted to consider this a bug. At the least it's not expected.

Please or to participate in this conversation.