Предположим, у нас есть 3 таблицы, как это:Yii реляционная модель один-к-новейший
--------- --------------- -------------------
| USER | | USER_STATUS | | STATUS_DICT |
|-------| |-------------- |------------------
| id | | id | | id (int) |
| name | | user_id | | status (string) |
| email | | status_id | -------------------
--------- | timestamp |
---------------
Каждый user
имеет много статусов (user_status
), связанные с user.id <-> user_status.user_id
. Каждый user_status
имеет одну связанную запись в status_dict
, которая является строковой меткой статуса int (например, 0 = активна).
Что я хочу, так это сделать модель пользователя для получения статуса последнего пользователя с использованием отношения. Установить отношения:
/* User model */
public function relations() {
return array(
'status' => array(self::HAS_ONE, 'UserStatus', 'user_id', 'order'=>'status.id DESC'),
);
}
и
/* UserStatus model */
public function relations() {
return array(
'status' => array(self::BELONGS_TO, 'StatusDictionary', 'status_id'),
'user' => array(self::BELONGS_TO, 'User', 'user_id'),
);
}
Тогда, когда я звоню User::model()->findByPk(1)->status
я последний статус для пользователя # 1.
НО.
Когда я хочу найти всех пользователей с указанным статусом, он не работает так, как я хочу. Вместо того, чтобы получать только пользователей с указанным статусом (последняя запись в user_status
), я получаю всех пользователей, которые хотя бы раз имели этот статус.
Что я должен сделать, чтобы сделать отношение одним из самых новых (я называю это так для цели этого случая)? Я видел this article, и он выполняет эту работу, но мне интересно, есть ли способ достичь этого с помощью соглашений Yii.
Я хотел объявить названный объем, как это:
/* in User model */
public function withStatus($status) {
if(!is_numeric($status) && !is_null($status)) {
$status = StatusDictionary::model()->find('lower(name)=lower(:name)', array(':name' => $status))->getAttribute('id');
}
$this->getDbCriteria()->mergeWith(array(
'condition' => (is_null($status) ? 'status.status_id IS NULL' : 'status.status_id=:statusId'),
'params' => array(':statusId' => $status),
'with' => array('status')
));
return $this;
}
Но это не работает либо, User::model()->withStatus(0)->findAll()
возвращает все пользователи с соответствующей записью в user_status
с user_status.status_id = 0
, даже если некоторые из пользователей имеют новый, другой статус.
Заранее благодарим за любую помощь.
Это почти хорошее решение - почти, потому что оно не возвращать пользователей без какого-либо статуса. Однако ваше решение подтолкнуло меня к тому, чтобы что-то проверить, и я нашел, как и должно быть (я отправлю ответ). – Wirone