I need to eager load relationship within laravel policy The problem is i use the laravel policy inside yajra-datatable which will load it (the policies) line by line
Here's the code looks like :
public function create(User $user)
{
$user->load('sections');
$sections = collect($user->sections->toArray())->pluck('name');
return
in_array($user->role_id,[3,4])
&& in_array('Produksi', $sections->toArray())
&& Session::get('productionPlans-branch') !== 'all'
&& Session::get('productionPlans-period') !== 'all';
}
and i use it in my yajra-datatable like so :
public function table(Request $request)
{
$query = ProductionPlan::with(['branch','product.category','period'])->orderBy('created_at');
return \Yajra\DataTables\DataTables::of($query)
->addIndexColumn()
->addColumn('action', function($row) {
if ($request->user->can('create', $row)) {
return '<a href="javascript:void(0)" onclick="show('. $row->id .')">Add</a>';
}
})
->rawColumns(['action'])
->make(true);
}
so every line will load the relation again and again
I'm expecting more efficient way to load them just once instead of load the relation line by line How can i achieve this ?
Update :
I tried to use accessor on User model to append the relations with sections table
protected $appends = ['sections'];
public function getSectionsAttribute ()
{
return $this->attributes['sections'] = $this->sections()->first();
}
This was success for only the FIRST relation only, i tried to remove the first() method but got the error PDO serialization instead
Serialization of 'PDO' is not allowed
I think Laravel policies uses the exact object it is called on. So $this->user->can(...) actually is the same object that is being passed as first parameter to the create(User $user) policy method.
In that case, I would try to load it before you call the ->can method inside the closure.
The code could look like this:
public function table(Request $request)
{
$query = ProductionPlan::with(['branch','product.category','period'])->orderBy('created_at');
$user = $request->user;
$user->load('sections');
return \Yajra\DataTables\DataTables::of($query)
->addIndexColumn()
->addColumn('action', function($row) use ($user) {
if ($user->can('create', $row)) {
return '<a href="javascript:void(0)" onclick="show('. $row->id .')">Add</a>';
}
})
->rawColumns(['action'])
->make(true);
}
And then you also have to remember to remove the $user->load('sections');
from inside the create() method in the policy.
This is very important :-)