Yii2 - hasOne替代品

WeS*_*See 1 database activerecord yii2

在Yii2中,我们使用相关模型

class AnyClass {
    ...
    public function getUser()
    {
        return $this->hasOne(User::className(), ['id' => 'user_id']);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个实现有什么区别?

class AnyClass {
    ...
    public function getUser()
    {
        return User::find()->where(['id' => $this->user_id]);
    }
}
Run Code Online (Sandbox Code Playgroud)

我计划使用多个复合键,并认为第二个版本更容易扩展复合键的附加条件.

小智 8

您可以在关系本身中添加复合键或额外条件:

public function getUser() {
    return $this->hasOne(User::className(), ['id' => 'user_id'])
       ->onCondition(['user.status' => 'active'])
}
public function getAdultUser() {
    return $this->getUser()->where(['user.adult' => 1])
}
Run Code Online (Sandbox Code Playgroud)

还要记住,当您通过getter方法调用时,会加载实际的相关记录:

  • $anyClass->user将返回User的实例.
  • $anyClass->getUser()将返回ActiveQuery对象.

因此,您可以随时随地添加额外条件:

$anyClass->getUser()->where(['>', 'user.created_at', strtotime("previous month")])
Run Code Online (Sandbox Code Playgroud)

您的实现并不代表两个对象之间的实际关系.它将工作懒加载数据,如果 AnyClass是加载的记录:AnyClass::findOne(1)->user.

只有这样,才能奶源聚合数据或多个结果组,其中延迟加载是不切实际的,是通过使用hasOne的hasMany,并指定表之间的逻辑关系(在这种情况下['id' => 'user_id']是指之间的严格关系AnyClassUser).

AnyClass::find()->with(`user`)->limit(1000); 
AnyClass::find()->joinWith(`user`);
SomeOtherClass::find()->joinWith('anyClass.user')->where('user.is_valid');
Run Code Online (Sandbox Code Playgroud)