我有用户个人资料,允许用户互相留言。 (想想Facebook / MySpace)......
如果profile_messages
表包含以下字段id
,user_id
,author_id
,parent_id
和message
,我将如何有效以线程布局显示它们?
注意:评论只有1级深度。
目前,我正在获取所有相关评论,然后重建集合以在每个项目上设置$messages
子集合replies
。
$messages = new Collection();
$replySets = [];
foreach ($user->profileMessages as $message)
{
$parentId = $message->parent_id;
if ($parentId == 0)
{
$messages->put($message->id, $message);
}
else
{
$replySets[$parentId][] = $message;
}
}
foreach ($replySets as $parentId => $replies)
{
$parent = $messages->get($parentId);
if (isset($parent))
{
if ( ! isset($parent->replies))
{
$parent->replies = new Collection();
}
foreach ($replies as $reply)
{
$parent->replies->push($reply);
}
}
}
// Pass $messages to the view
这非常有效。但是,我不禁想到有更好的方法可以做到这一点......有没有更好的方法来做到这一点,或者也许是一种利用关系来获得与{{1}匹配的结果集的方法结构?
答案 0 :(得分:3)
根据您的描述,我假设您有根user_id
指向用户的根消息,已发送消息。并回复那些与user_id
相关但与parent_id
无关的根消息。
所以:
$user->load('messages.replies.author');
foreach ($user->messages as $message)
{
$message; // root message
$message->replies; // collection
$message->replies->first(); // single reply
$message->replies->first()->author;
}
与以下关系:
// user model
public function messages()
{
return $this->hasMany('Message')->where('parent_id', '=', 0);
// you could also create RootMessage model with global scope instead of this where
}
// message model
public function replies()
{
return $this->hasMany('Message', 'parent_id');
// again, here you can create separate Reply model if you like
}
public function author()
{
return $this->belongsTo('User', 'author_id');
}
public function user()
{
return $this->belongsTo('User');
}