yii结合模型关系

时间:2013-04-07 13:21:44

标签: yii relationship

我想知道如何(如果可能的话)在Yii模型中组合(联合)关系。

我有以下型号:

  • 用户
  • 国家
  • 项目

地理层次关系是:

  • 国家有很多省
  • 省有很多城市
  • 城市有很多项目

国家和省级有许多项目:'通过'=>'城市'

用户 - 地理关系有点复杂:

  • 用户 - 国家/地区(多对多)
  • 用户 - 省(多对多)
  • 用户 - 城市(多对多)

因此,可以将用户分配到任何地理级别,并隐含分配给该级别的所有子级别。

例如。分配到加拿大,加利福尼亚和芝加哥的用户可以访问:

  • 加拿大所有城市所有省份的所有项目
  • 以及加利福尼亚州所有城市的所有商品
  • 以及芝加哥的所有项目

因此,我希望看到哪些项目是通过其地理位置分配给用户的。所以我想设置一个关系,只需访问“items”属性(例如$ myUser->项目),即可访问分配给它们的所有项目。

实际上,我想将这些组合成一个名为“items”的单一关系:

'countryItems' => array(self::HAS_MANY, 'Item', array('id' => 'country_id'), 'through'=>'countries'),
'provinceItems' => array(self::HAS_MANY, 'Item', array('id' => 'province_id'), 'through'=>'provinces'),
'cityItems' => array(self::HAS_MANY, 'Item', array('id' => 'city_id'), 'through'=>'cities'),

1 个答案:

答案 0 :(得分:4)

这里的问题是,您无法创建一个SQL语句来获取用户的所有不同项目,因为项目和用户之间的连接不明确:一个项目可以通过不同的路径连接到用户。这意味着,对于用户来说,同一个项目甚至可以有多个连接(例如,通过城市和省份)。

您可以尝试为用户和项目之间的每条可能路径添加JOIN(通过国家/地区,省和城市)。但是所提到的含糊不清将一直以你的方式:你可以得到一个包含重复的结果。

由于原始SQL中没有解决方案,因此仅靠Yii关系无法解决问题。不过,你总是可以写一个getter:

public getItems()
{
    $items = array();

    foreach($this->countryItems as $item)
        $items[$item->id] = $item;

    foreach($this->provinceItems as $item)
        $items[$item->id] = $item;

    foreach($this->cityItems as $item)
        $items[$item->id] = $item;

    return $items;
}

这实际上为您提供了$items属性,其中包含该用户的所有不同项目。