Jpv
Jpv

Reputation: 123

Laravel Eloquent pass Attribute to Relationship

I'm trying to load a relationship with eager loading. But, would like to pass an attribute to the relationship function.

(Laravel 6.x)

Model - taxChildren() requires an ID

public function taxChildren($moduleId)
{
    return $this->hasMany($this, 'parent')->where('module', '=', $moduleId')->orderBy('created_at', 'asc');
}

Controller

$departments = tax::where([
        ['module', '=', $this->departmentsModuleId],
    ])
        ->whereNull('parent')
        ->with([
            'taxChildren' => ['moduleId', '2']
        ])
        ->get();

Now , i know that i can pass a query to my relationship like so:

$departments = tax::where([
        ['module', '=', $this->departmentsModuleId],
    ])
        ->whereNull('parent')
        ->with([
            'taxChildren' => function($query){
                $query->where('module', '=', $this->departmentsModuleId);
            },
        ])
        ->get();

but i will be using this often with multiple relations that are similar. Anyone have an idea how to achieve this? Thanks!

Upvotes: 1

Views: 938

Answers (1)

Malkhazi Dartsmelidze
Malkhazi Dartsmelidze

Reputation: 4992

You can't pass argument direcly to the relationship function but this can be done with model properties

Mymodel.php
class MyModel extends Model {
    protected $moduleId = null;

    public function taxChildren(){
        return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
    }
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {

    public function controllerMethod(){
        $query = new MyModel;
        $query->moduleId = 1;

        $departments = $query::where([
            ['module', '=', $this->departmentsModuleId],
        ])
        ->whereNull('parent')
        ->with(['taxChildren'])
        ->get();
    }
}

Also you can use laravel query scopes to set modelId property . I think that is much cleaner code

Mymodel.php
class MyModel extends Model {
    protected $moduleId = null;

    public function scopeMudule($q, $module_id){
        $this->moduleId = $module_id;
        return $q;
    }

    public function taxChildren(){
        return $this->hasMany($this, 'parent')->where('module', '=', $this->moduleId)->orderBy('created_at', 'asc');
    }
}
MyController.php
use App\MyModel;
...
class MyController extends Controller {

    public function controllerMethod(){
        $departments = $query::module(1)->where([
            ['module', '=', $this->departmentsModuleId],
        ])
        ->whereNull('parent')
        ->with(['taxChildren'])
        ->get();
    }
}

Upvotes: 1

Related Questions