PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Friday, January 28, 2022

[FIXED] Laravel Eloquent's ->load() With Callback Not Affecting Resultset

 January 28, 2022     eloquent, laravel, php     No comments   

Issue

I am looking to take a parent object (Person, in this example) and load a bunch of relationships on it, many of which have custom query parameters passed to ->load() as a callback. For example:

public function some_method(Request $request, Person $person) {

$person->load([
   'things' => function ($query) {
      $query->where('status', 'active')
         ->whereDate('created_at', '<', '2021-01-01');
   },
   'other_things' => function ($query) {
      $query->where('status', 'active')
         ->where('color', 'red');
   },
   ... Many more callback-based relationships ...
]);

When I pass this to a Blade template with return view('...', compact('person')) and begin looping over some of the relationships like this:

@foreach ($person->things as $thing)
{{ $thing->status == 'active' ? 'Active' : 'Inactive' }}
@endforeach

I get many Things that are inactive and do not conform to the ->whereDate() query from the ->load() function in the controller. I would expect the custom callbacks in the load([...]) to filter the resulting relationship, but when accessing the relationships in Blade templates, it seems the query is executed as if there are no callback functions present.

I have tried using with() but that does not appear to be the correct way to approach it, considering I am injecting the Person in the URI. I have also tried using ->map() with various loop structures, but those also get overwritten by what appears to be a second round of Eloquent calls to the database.

What do I need to do in order to have the Blade template "respect" the custom callback queries that I wish to use to filter the records loaded onto the parent object?

Thanks!


Solution

There are a few things you can try.

Option 1

this should not be needed but you can try and override the $person with the loaded result.

$person = $person->load();

Option 2

As of Laravel 8.43 you can use Model::preventLazyLoading(! app()->isProduction()); in the boot method of app/Providers/AppServiceProvider.php. This will prevent any lazy loading , also in views. If there is lazy loading it will return an error.enter image description here image source



Answered By - SuperDJ
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing