У меня есть реляционная запись, подобная следующей:
- Есть пользователи (пользователи таблицы) с идентификаторами
- Существуют категории (категории таблиц) с идентификатором, именем
- Есть статьи (таблицы статей) с id, body, category_id
- Тогда есть таблица read_articles с article_id, user_id
Таким образом, пользователь может видеть список всех статей в категории. Они могут щелкнуть статью, и она добавит запись (user_id, article_id) в таблицу read_articles.
Я хочу иметь возможность использовать ActiveRecord от Yii, чтобы получать все статьи из данной категории, которые не были прочитаны текущим пользователем, и отображать их. Я немного думал об этом с точки зрения SQL, но я не уверен, как вписать его в мои настройки ActiveRecord. Моей первой идеей была параметризованная область действия активной записи Статьи:
public function unread( $userId )
{
$this->getDbCriteria()->mergeWith( array(
'alias' => 'articles',
'condition' => 'not exists (SELECT * '
. 'FROM user_read_articles '
. 'WHERE articles.id=user_read_articles.article_id '
. 'AND read_articles.user_id=' . (int)$userId
. ')',
) );
}
Кажется, это работает, но мне это кажется очень грязным.
Есть ли более чистый способ сделать то, о чем я говорю в ActiveRecord? Или мне стоит подумать о переходе к более простому SQL и самому обрабатывать подобные вещи (но потерять много приятных возможностей AR)?
Редактировать Вот отношения для вышеупомянутых моделей: (Отказ от ответственности, они усечены только для соответствующих частей)
UserActiveRecord
public function relations()
{
return array(
'categories' => array(
self::HAS_MANY,
'UserCategoryActiveRecord',
'user_id' ),
// I added this early using gii, never really used it...
'readArticles' => array(
self::HAS_MANY,
'UserReadArticleActiveRecord',
'user_id' ),
);
}
UserCategoryActiveRecord
public function relations()
{
return array(
'user' => array(
self::BELONGS_TO,
'UserActiveRecord',
'user_id' ),
'articles' => array(
self::HAS_MANY,
'ArticleActiveRecord',
'category_id',
'order' => 'articles.pub_date DESC' ),
);
}
ArticleActiveRecord
public function relations()
{
return array(
'category' => array(
self::BELONGS_TO,
'CategoryActiveRecord',
'category_id' ),
);
}
Я также создал «UserReadArticleActiveRecord» еще при создании, но я никогда не использовал эту модель, и она почти пуста.
Честно говоря, я думал о том, чтобы в любом случае перейти на Symfony2 и Doctrine и просто убрать активную запись. Я знаю, что это не решает эту проблему, но я мог бы просто отбросить это и оставить свое текущее решение на время.