Laravel根据关系方法的结果急于加载关系


Laravel eager load a relationship based on the result of relationship method

我有以下实体:

用户

class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
 * The database table used by the model.
 *
 * @var string
 */
protected $table = 'members';
protected $primaryKey = 'member_id';
public function licences(){
    return $this->hasMany('Licence', 'subid', 'member_id');
}

}

执照

class Licence extends 'Eloquent {
protected $table = 'licence';
protected $primaryKey = 'id';
protected $active = false;
const DATE_FORMAT = 'Y-m-d';
protected $fillable = [];
public function __construct(){
    $this->checkifIsActive();
}
public function owner(){
    return $this->belongsTo('User', 'member_id', 'subid');
}
public function checkifIsActive(){
    if($this->start_date <= date($this->DATE_FORMAT) && $this->end_date >= date($this->DATE_FORMAT)) $this->active = true;
}

}

一个用户可以拥有多个许可证,并且该用户拥有的许可证可以是活动的,也可以是非活动的 - 这取决于许可证的开始和结束日期。

我正在尝试加载一个用户对象,同时拉入他们的许可证,但只有那些处于活动状态的许可证。

在许可证模型中,当对象实例化时,我将"active"变量设置为 true,因此我们有办法知道许可证的状态。

到目前为止,我尝试过的代码是:

return User::findOrFail($id)->with('licence.active')->get();

但是,这并不完全正确 - 因为没有在"license.active"上进行实际条件检查。

我将如何返回由 ID 加载的用户,以及他们关联的将布尔"活动"变量设置为"true"的许可证?

您可以使用预先加载约束来查询关系,如下所示;

$user = User::with(array('license' => function($query){
    $query->where('start', '<=', Carbon::now())
    $query->where('end', '>=', Carbon::now())
}))->find($id);

然后,这将仅返回处于活动状态的许可证。

(可选)您可以像这样查询关系的结果;

public function activeLicences(){
    return $this->hasMany('Licence', 'subid', 'member_id')->where('start', '<=', Carbon::now())->where('end', '>=', Carbon::now());
}

然后,您所要做的就是执行以下操作即可获得结果;

$user = User::with('activeLicenses')->find($id)

请注意:这尚未经过测试。