我有一个模型,其中定义了一些关系,如下所示。
public function relations()
{
return array(
'linkingTable' => array(self::HAS_MANY, 'LinkingTable', array('this_id'=>'id'), 'scopes'=>array('valid')),
'linkedItems' => array(self::HAS_MANY, 'LinkedItem', array('linked_item_id'=>'id'), 'through'=>'linkingTable', 'scopes'=>array('valid')),
);
}
链接表和链接项都有一个有效的范围:
public function scopes() {
return array(
'valid'=>array(
'condition'=>"t.`valid`=1",
),
);
}
为了使生成的联接查询与关系作用域一起工作,我不得不修改作用域如下:
public function scopes() {
return array(
'valid'=>array(
'condition'=>"`linkingTable`.`valid`=1",
),
);
}
和:
public function scopes() {
return array(
'valid'=>array(
'condition'=>"`linkedItems`.`valid`=1",
),
);
}
问题是,当直接从链接模型中使用时,这些作用域将不起作用,即:
$linkedItems = LinkedItem::model()->valid()->findAll();
导致错误,说明linkedItems
不是已定义的别名。当然,这是可以理解的。它还导致任何其他想要拥有某些LinkedItems的模型都需要以完全相同的方式定义关系。
是为每个用例定义不同范围的唯一解决方案,如下所示:
public function scopes() {
return array(
'valid'=>array(
'condition'=>"t.`valid`=1",
),
'validForModelRelation'=>array(
'condition'=>"`linkedItems`.`valid`=1",
)
);
}
这感觉有点封闭。我想知道是否有更好的方法?
您需要能够获取表的当前别名。t
(当它单独存在时),或关系名称(当它是相关模型时)。在相关模型的范围内,您可以使用:
public function scopes() {
return array(
'valid'=>array(
'condition'=>$this->tableAlias.".`valid`=1",
),
);
}
但是,如果在defaultScope
中使用它,则需要使用$this->getTableAlias(false, false).
作为参数,以防止试图查找别名的无限循环。
编辑:点丢失
您之前需要DOT'condition'=>$this->tableAlias。".valid
=1",