Yii2 ActiveQuery использует ИЛИ в массиве ссылок

Я хочу использовать оператор ИЛИ в массиве $link в функции hasMany в классе, расширенном ActiceRecord. Например, я хочу получить транзакции, связанные с учетной записью пользователя. В sql это будет что-то вроде SELECT * FROM transactions WHERE fromAccountId = :id OR toAccountId = :id Но как я могу написать это с помощью Yii2

    public function getTransactions() {
        return $this->hasMany(Transaction::className(), [
            'fromAccountId' => 'id',
            'toAccountId' => 'id'
        ]);
    }

person Богдан Горбатенко    schedule 14.10.2014    source источник


Ответы (3)


Link ActiveQuery работает с ключами массива как с именем столбца, со значениями - как со значением столбца.

Ключи массива должны быть столбцами таблицы для этого отношения, а значения массива должны быть соответствующими столбцами из основной таблицы.

Поскольку код не работает (where (fromAccountId, toAccountId) IN ('id','id')):

[
    'fromAccountId' => 'id',
    'toAccountId' => 'id'
]

Вы можете переписать поведение hasMany в getTransactions().

public function getTransactions() {
    $query = Transaction::find();
    $query->multiple = true;
    return $query->where(['OR',
        ['fromAccountId' => $this->id],
        ['toAccountId' => $this->id]
    ]);
}

Как и ожидалось, он поддерживает нативное поведение:

$model->getTransactions() // return as \yii\db\ActiveQuery
$model->transactions // return as array of Transactions models

Но не работает для $model->find()->with('transactions'), поскольку для with требуется настройка $query->link. Вместо with нужно использовать join....

person Evgeniy Tkachenko    schedule 05.05.2015

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

return $this->find()->join('LEFT JOIN', 'transaction', 'fromAccountId = id OR toAccountId = id')->all();

Возможно, вам нужно использовать tablename.id!

person Adam Fentosi    schedule 16.10.2014

Я не пробовал это, но вы можете попробовать что-то вроде

public function getTransactions() {
        return $this->hasMany(Transaction::className(), ['1' => '1'])->where('fromAccountId = id OR toAccountId = id');
    }

Идея состоит в том, чтобы создать соединение без условия (или с фиктивным условием), а затем использовать его, чтобы получить фактические результаты, которые вы хотите. Это может означать серьезные проблемы с производительностью.

person Mihai P.    schedule 14.10.2014
comment
['1' => '1'] Получение неизвестного свойства: Model::1 - person Evgeniy Tkachenko; 05.05.2015
comment
Получение неизвестного свойства: Модель :: 1 - person Shaig Khaligli; 31.07.2016