【问题标题】:Yii: A HAS_MANY B, B HAS_MANY C, find count of C belonging to AYii: A HAS_MANY B, B HAS_MANY C, 找到属于A的C个数
【发布时间】:2025-04-14 00:20:04
【问题描述】:

基本上,我有 3 张桌子。

house_table
===========
house_id


floor_table
===========
floor_id
house_id


room_table
===========
room_id
floor_id
is_occupied

房子有很多层,一层有很多房间。一个房间属于一层,一层属于一个房子。 gii自动创建的对应模型为HouseTableFloorTableRoomTable

我需要的是findAll()那些有空房间的房子。

我该怎么做?像这样?

class HouseRecord extends CActiveRecord {
    public function relations() {
        return array(
            'FREE_ROOM_COUNT' => array(self::STAT ...???...),
        );
    }
}

当然,我可以用 SQL 来做,但需要这样做,因为findAll() 的结果被用作网格中的数据提供者。

更新

按照 tinybyte 的建议,这就是最终奏效的方法。

public function relations() {
    return array(
        'FREE_ROOM_COUNT' => array(
            self::STAT ,
            'FloorTable',
            'house_id',
            'select' => 'COUNT(rt.floor_id)',
            'join' => 'INNER JOIN room_table rt ON t.floor_id = rt.floor_id',
            'condition' => 'rt.is_occupied = 0',
        ),
    );
}

并被这样使用:

    $criteria = new CDbCriteria;

    $criteria->with = array('FREE_ROOM_COUNT');
    $criteria->together = true;

    $provider = new CActiveDataProvider(HouseTable::model(), array(
        'criteria'=>$criteria,
        'pagination' => array(
            'pageSize' => 1,
        ),
    ));

    $this->widget('zii.widgets.CListView', array(
        'dataProvider'=>$provider,
        'itemView'=>'house',
    ));

不幸的是,事实证明不能将这些 STAT 关系用作条件! (在此确认:Using STAT relation in CActiveDataProvider criteria)。

【问题讨论】:

  • 我加入书签是因为它看起来很有趣。我可以告诉你,你可以拥有其他类型的数据提供者,甚至可以自己制作。例如:class ArrayAsObjectDataProvider extends \CArrayDataProvider { public function __construct($rawData,$config=array()) { foreach($rawData as $data) { $object = new \stdClass(); foreach($data as $key=>$value) { $object->$key = $value; } $this->rawData[] = $object; } foreach($config as $key=>$value) $this->$key=$value; } }
  • 我当然希望可以通过关系来完成。
  • yiiframework.com/wiki/319/…看看有没有帮助

标签: sql database yii


【解决方案1】:

我认为这应该可以解决问题

'FREE_ROOM_COUNT' => array(
   self::STAT ,
  'Floor' ,
  'house_id' 
  'select' => 'count(rt.floor_id)' , // or count(rt.room_id)
  'join' => 'Inner join room_table rt ON Floor.floor_id = rt.floor_id' ,
),

【讨论】:

  • 我得到CStatRelation.alias 未定义。有什么想法吗?
  • 我通过修复一些东西让它工作了。您可能应该在此处更新代码。