Laravel 从其关系中使用 where() 进行预加载

Laravel eager loading with where() from its relation

我有 3 个 table 有关系

预算Table:

Field Type Null Key Default Extra
id bigint(20) unsigned NO PRI NULL auto_increment
user_id bigint(20) unsigned NO MUL NULL
purpose varchar(255) NO NULL
delivery_plan varchar(255) NO NULL
status varchar(255) NO NULL
created_at timestamp YES NULL
updated_at timestamp YES NULL

周期 table :

Field Type Null Key Default Extra
id bigint(20) unsigned NO PRI NULL auto_increment
name varchar(255) NO NULL
term_id bigint(20) unsigned NO NULL
created_at timestamp YES NULL
updated_at timestamp YES NULL

条款table:

Field Type Null Key Default Extra
id bigint(20) unsigned NO PRI NULL auto_increment
name tinyint(4) NO NULL
status varchar(255) NO NULL
created_at timestamp YES NULL
updated_at timestamp YES NULL

预算模型:

public function period()
{
    return $this->belongsTo(Period::class, 'delivery_plan', 'name');
}

时期模型:

public function budgets()
{
    return $this->hasMany(Budget::class, 'delivery_plan', 'name');
}

public function term()
{
    return $this->belongsTo(Term::class);
}

术语模型:

public function periods()
{
    return $this->hasMany(Period::class);
}

所以每个预算属于一个时期,而时期属于一个学期。 然后我想根据术语名称查询预算。 那么如何使用 laravel eager loading 查询呢?

你使用 whereHas 方法:

$builder->whereHas('relationName', function (Builder $builder){ /* your query */ });

如果你没有任何申请条件,你可以直接使用 whereHas 不带回调

如果需要,您可以链接多个 whereHas

Budget::whereHas("period", function(Builder $builder) {
            $builder->whereHas('term', function(Builder $builder) {
                $builder->where('name', '=', 'test');
            })
        })

您甚至可以使用点符号来简化它

Budget::whereHas("period.term", function(Builder $builder) {
            $builder->where('name', '=', 'test');
        })

只需使用 hasManyThrough。因此,您可以通过 Period

BudgetTerm 之间 link