Laravel-Backpack / CRUD

Build custom admin panels. Fast!
https://backpackforlaravel.com
MIT License
3.08k stars 886 forks source link

Filtering a 'with' clause #245

Closed sijones-uk closed 7 years ago

sijones-uk commented 7 years ago

According to @tabacitu's reply in #101, it's possible to add an eager-loaded relationship clause (i.e. a 'with' clause) to the query via addClause(). I've got a Campaign model and CampaignSession model with the 'campaign_id' column on the campaign_sessions table being a foreign key of the 'id' column on the campaigns table. The basic 'with' clause in my CampaignsCrudController is then:

$this->crud->addClause('with', 'campaignSessions');

This works fine, but I need to specify additional query constraints for the eager-loaded query. I tried something like this without success:

$this->crud->addClause('with', ['campaignSessions' => function ($query) {
    $query->select(['campaign_id', 'name AS campaign_name']);
}]);

Using this constrained clause, I looked at the contents of $this->crud->query and found that although the 'eagerLoad' closure's parameters contained a $query object, the latter was empty.

Is it possible to have a constrained 'with' clause?

tabacitu commented 7 years ago

Hi @sijones-uk ,

Never tried it myself, but it should work. Maybe try a different operation in the closure, see if that one applies?

If not, since the $crud property is public, you can also do this:

$this->crud->query = $this->crud->query->with(['campaignSessions' => function ($query) {
    $query->where('title', 'like', '%first%');
}]);

Does this fix it?

Cheers!

sijones-uk commented 7 years ago

Thanks Christian. I tried both of the following without success:

$this->crud->addClause('with', ['campaignSessions' => function ($query) {
    $query->where('id', '=', 1);
}]);
$this->crud->query = $this->crud->query->with(['campaignSessions' => function ($query) {
    $query->where('id', '=', 1);
}]);

When I looked at the query output via dd($this->crud->query); for the latter, I got the result you can see here ($query is empty):

laravel_backpack_eager_load

The weird thing is that the eager loading works, but the closure function containing the constraints is never used.

sijones-uk commented 7 years ago

After more investigation, I found that if I create an Eloquent Builder object and attempt to add the eager loading via the setEagerLoads() method, the constraint isn't added. It seems that there's a wider problem, so I reported it here. The only way I'd be able to add the constraint using Backpack would be if I could somehow add a 'with' clause to $this->crud->model. It doesn't look like that's possible though.

OwenMelbz commented 7 years ago

@sijones-uk tried using scopes?

OwenMelbz commented 7 years ago

Just closing to tidy up, if you need more help feel free to shout :)

tabacitu commented 7 years ago

@sijones-uk ,

Just pushed an update:

Cheers!

sijones-uk commented 7 years ago

Thanks @tabacitu

victorlap commented 7 years ago

@sijones-uk Have you had any luck constraining the eager loaded relationship?

seyacat commented 3 years ago

It work for me

$this->crud->addClause('orWhereHas', 'juego' , function ($query) use($permission) { $query->where('nombre', '=', $permission); });