Собствено, хочу узнать у народа, как бы вы стали реализовывать схему а-ля твиттер с потоком сообщений людей, которых вы читаете? Сейчас использую вот такую схему:
Таблицы:
users
messages (fk - user_id)
followers (fk - leader_id, follower_id)
Вроде бы проблем тут нет (разве что логично не иметь PK в таблице followers, но AR не позволяет пока этого). Вопрос встал в другом - как получить и вывести сообщения пользователей, на которых я подписан?
Сейчас делаю так:
// get timeline
public function getFriends($limit=20, $offset=0)
{
// new criteria
$criteria=new CDbCriteria();
// setup
$criteria->condition='follower_id = :uid';
$criteria->select='user.messages.*';
$criteria->params=array(':uid'=>Yii::app()->user->id);
$criteria->limit=$limit;
$criteria->offset=$offset;
$criteria->together=true;
$criteria->with=array('user.messages');
$criteria->order='messages.created_at DESC';
$results=array();
// return results
$models = Followers::model()->findAll($criteria);
foreach($models as $model) {
foreach($model->user->messages as $message) {
$results[$message->id]=$message;
}
}
ksort($results, SORT_NUMERIC);
return array_reverse($results);
}
Вроде как работает, но подозреваю не лучшую производительность у такого подхода. Что посоветуете?
public function getFriendMessages($limit=20, $offset=0)
{
$criteria = new CDbCriteria;
$criteria->join = 'INNER JOIN `followers` ON `t`.`user_id` = `followers`.`leader_id`';
$criteria->compare('follower_id', $this->user_id);
$crtieria->order = 'created_at DESC'; // почему-то тут не работает, но можно добавить в defaultScope класса Message
$criteria->offset = $offset;
$criteria->limit = $limit;
return Message::model()->with('user')->findAll($criteria);
}
Затем в контроллере, получив юзера, можно воспользоваться данным методом для получения списка сообщений (вместе с авторами):