次のように定義されたいくつかの関係を持つモデルがあります。
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",
)
);
}
これはちょっとゴツい気がします。これを行うより良い方法があるかどうか疑問に思っていますか?