0

我有一张桌子Friend (PersonA, PersonB)。这些是 的外键Person(id, name)

我想在它们之间创建一个 Yii 关系。这就是我想出的:

public function relations() {
    return array(
        'friends1' => array(self::HAS_MANY, 'Friend', 'PersonA'),
        'friends2' => array(self::HAS_MANY, 'Friend', 'PersonB'),
    );
}

有没有办法将这两种关系合二为一?我希望有这样的事情:

public function relations() {
    return array(
        'allFriends' => array(self::HAS_MANY, 'Friend', 'PersonA, PersonB'),
    );
}

有任何想法吗?

编辑#1:

为了完整起见,让我们也假设我想订购friends1friends2喜欢这样:

public function relations() {
    return array(
        'friends1' => array(self::HAS_MANY, 'Friend', 'PersonA', 'order'=>'id ASC'),
        'friends2' => array(self::HAS_MANY, 'Friend', 'PersonB', 'order'=>'id ASC'),
    );
}
4

2 回答 2

1

这个解决方案对我有用:

覆盖__get模型中的函数:

public function __get($name)
{
    if(($name == 'friends1') || ($name == 'friends2')) {
        return parent::__get('friends1') + parent::__get('friends2');
    }
    else
        return parent::__get($name);
}
于 2016-03-15T17:04:11.543 回答
0

在我正在做的事情中,我遇到了完全相同的事情。我所做的是我创建了另一个函数来将这两个关系编译成一个数组。这样做的原因是,即使您要将这两个关系结合起来,每次您仍然需要测试 PersonA 或 PersonB 是否是当前用户的 id,并使用另一个 id 来提取好友信息。这是我在模型中创建的函数:

public function getFriends() {
    $all_friends = array();
    foreach($this->friends1 as $friend) {
        if($friend->PersonA == $this->id) {
            $all_friends[] = $friend->PersonA;
        } else {
            $all_friends[] = $friend->PersonB;
        }
    }
    foreach($this->friends2 as $friend) {
        if($friend->PersonA != $this->id) {
            $all_friends[] = $friend->PersonA;
        } else {
            $all_friends[] = $friend->PersonB;
        }
    }
    return $all_friends;
}

另一种选择:

public function getFriends() {
    $criteria = new CDbCriteria;
    $criteria->compare('PersonA',$this->id);

    $criteria2 = new CDbCriteria;
    $criteria2->compare('PersonB',$this->id);

    $criteria->mergeWith($criteria2,'OR');

    $friends = Challenge::model()->findAll($criteria);
    return $friends;
}

然后对于任何人,你可以说:

$person = Person::model()->findByPk(1);
$friends = $person->friends;

CActiveDataProvider或者,您可以发送回一个可以用来进行排序和其他事情的数组,而不是一个数组。你可以这样做:

public function getFriends() {
    $criteria = new CDbCriteria;
    $criteria->compare('PersonA',$this->id);

    $criteria2 = new CDbCriteria;
    $criteria2->compare('PersonB',$this->id);

    $criteria->mergeWith($criteria2,'OR');

    return new CActiveDataProvider('Friend', array(
        'criteria' => $criteria,
    ));
}

然后因为你有 CActiveDataProvider 你可以排序:

$friends = $user->friends->getData(); //not sorted or anything
//or you can manipulate the CActiveDataprovider
$data = $user->friends;
$data->setSort(array(
    'defaultOrder'=>'PersonA ASC',
));
$friends = $data->getData();
于 2013-08-29T17:33:59.673 回答