2015-02-25 3 views
3

у меня есть две таблицы в базе данных, а именно «пользователь» и «user_user», которая связывает пользователей для пользователей (многие ко многим)Yii2 условно объединить на двух внешних ключей в одной таблице

в user_user есть две колонки " user_id_0 "и" user_id_1 "

Мне нужно получить всех пользователей, где текущий идентификатор пользователя равен user_id_0 ИЛИ user_id_1.

я могу добиться этого с помощью SQL:

select * from user u 
    inner join user_user uu 
    on uu. user_id_0 = u.id 
     or uu.user_id_1 = u.id 
    [where u.id = 1] 

В Yii2 я застрял с чем-то вроде этого:

($ это будет тип пользователя)

$this->hasMany(User::className(), ['id' => 'user_id_0']) 
     ->viaTable('user_user', ['user_id_0' => 'id'], 
      function($query) { 
       $query->orOnCondition(['user_id_1' => 'id']); 
     }); 

Теперь это не может работать, поскольку hasMany() ссылается только на один внешний ключ. Как мне сделать что-то вроде SQL выше? Присоединить два внешних ключа с помощью «или».

Это возможно или вы бы предложили другой дизайн базы данных? Цель здесь состоит в том, чтобы позволить пользователям иметь «друзей» или «подключения» к другим пользователям, например, в социальной сети.

+0

http://www.yiiframework.com/doc-2.0/guide-db-active-record.html#working-with-relational-data – ankitr

+0

Что делает этот запрос sql? Это для MySQL? – robsch

ответ

2

Я не уверен, работает ли это так, как вы ожидаете. Я не пробовал.

ИМО запрос должен выглядеть следующим образом (предполагается, что MySQL):

SET @id = 1; // or whatever 

SELECT  user.* 
FROM  user 
INNER JOIN user_user 
ON   user.id = user_user.id1 OR user.id = user_user.id2 
WHERE  user.id != @id AND (user_user.id1 = @id OR user_user.id2 = @id) 
GROUP BY user.id; 

Это может быть реализовано в классе пользователя, как это:

public function getConnectedPersons() { 

    return self::find() 
     ->select('user.*') 
     ->innerJoin('user_user', ['or', 
       'user.id=user_user.user_id_0', 
       'user.id=user_user.user_id_1' 
      ] 
     )->where(['and', 
       ['user.id' => $this->id], 
       ['or', 
        ['user_user.user_id_0' => $this->id], 
        ['user_user.user_id_1' => $this->id] 
       ] 
      ] 
     )->groupBy('user.id'); 
} 

Это возвращает объект ActiveQuery. Добавьте ->all(), если вы хотите получить массив пользователей напрямую.

Я надеюсь, что это сработает. Он не проверен. Но вы можете получить эту идею и дать мне отзыв, если что-то не так.

Это может быть не лучшее решение. Он не использует viaTable(), который также должен работать.