所以我使用的php框架是Laravel。我有一个评论表,评论允许有孩子评论。我按更新时间订购了评论:
$post->comments()->orderBy('updated_at')->paginate(10);
现在我想对注释进行分组,以便将具有相同父注释的所有子注释放在一起,即父注释,然后是所有子注释,然后是下一个父注释,然后是所有子注释评论一个一个,等等。如下:
现在这个订单不能通过一个简单的订单来完成,我的问题是:我可以用Laravel查询构建器/ eloquent完成这个,还是我必须手动订购?顺便说一句,我已经设置了Comment模型,以便可以通过以下方式获取其父/子:
$comment->parentComment;
$comment->childComments;
答案 0 :(得分:0)
您可以使用模型关系(self)来实现此目的,例如,假设这是您的comments
表:
id (PK) | content | post_id | user_id | comment_parent
------------------------------------------------------
1 | Hello | 1 | 1 | 0 <-- This is a parent because of 0
2 | Hi | 1 | 2 | 1 <-- child of 1
3 | Howdy | 1 | 3 | 1 <-- child of 1
将该表格读取为:总共有三条评论,第一条评论由User
user_id-1
发出,并且其他两位用户id
'发表了两条儿童评论s是user_id-2
和user_id-3
。
此处,comment_parent
列保留parent
和child
条评论之间的关系。值comment_parent
的{{1}}是父评论,而不是0
,例如,此处有两条评论0
comment_parent
,这意味着这两条评论是1
为id/PK
的评论的孩子。
所以,现在,在你的1
模型中声明这些方法:
Comment
然后在您的// Get only children of a comment
public function children()
{
return $this->hasMany('Comment', 'comment_parent');
}
// Get the user of comment
public function user()
{
return $this->belongsTo('User', 'user_id');
}
// Get the post of comment
public function post()
{
return $this->belongsTo('Post', 'post_id');
}
模型中声明此方法:
Post
现在,如果您这样做:
// Only parent comments
public function comments()
{
return $this->hasMany('Comment', 'post_id')->where('comment_parent', 0);
}
// All Comments
public function allComments()
{
return $this->hasMany('Comment', 'post_id');
}
然后你可以在你的视图中尝试这样的事情(可能在你的$post = Post::with('comments.children')->find(1);
中):
post.single.blade.php
这是一个想法,在这种情况下,默认情况下,您的评论{{ $post->title }}
{{ $post->body }}
<!-- Comment Template For Posting New Comments-->
@if($post->comments->count())
@foreach($post->comments as $comment)
{{ $comment->user->username }}
{{ $comment->body }}
@if($comment->children->count())
@foreach($comment->children as $childComment)
{{ $childComment->user->username }}
{{ $childComment->body }}
@endforeach
@endif
@endforeach
@endif
为0
,当评论是对另一条评论的回复时,请将其comment_parent
设为其父级comment_parent
。此外,您可以检查this article是否有其他方法。
答案 1 :(得分:0)
我意识到如果每次从数据库中获取数据时都要订购帖子的所有评论,最终可能会导致严重的性能问题。所以我的解决方法如下: 首先,这是我的评论表:
+-------------------+------------------+------+-----+---------------------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------------+------------------+------+-----+---------------------+----------------+
| id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| content | varchar(2000) | NO | | NULL | |
| author_id | int(10) unsigned | NO | MUL | NULL | |
| post_id | int(10) unsigned | NO | MUL | NULL | |
| parent_comment_id | int(10) unsigned | YES | MUL | NULL | |
| level | tinyint(4) | NO | | 1 | |
| sort_order | int(10) unsigned | NO | | NULL | |
| created_at | timestamp | NO | | 0000-00-00 00:00:00 | |
| updated_at | timestamp | NO | | 0000-00-00 00:00:00 | |
+-------------------+------------------+------+-----+---------------------+----------------+
请注意,有一个名为sort_order的字段,每次向帖子添加新评论时,以下两件事之一就会决定newComment的sort_order的值:
如果评论没有父母,那么
$ newComment-&gt; sort_order = Comment :: max('sort_order')+ 1;
如果评论有父级,那么
$parent = $newComment->parentComment;
$newComment->sort_order = $parent->sort_order + 1;
// for all the comments that have sort_order larger than the parent of the newly added comment, add their sort_order by 1
$comments_to_be_updated = Comment::where('sort_order', '>', $parent->sort_order)->get();
foreach ($comments_to_be_updated as $comment_to_be_updated) {
$comment_to_be_updated->sort_order += 1;
$comment_to_be_updated->save();
}
这样,每次添加新评论时,其位置/顺序都会由sort_order完成并记录,当我想要获取具有所需顺序的帖子的评论时,我只需要:
$后&GT;评论 - &GT; ORDERBY( 'SORT_ORDER') - &GT;分页(10);
现在,我不是说这是解决方案,但它已在我的方案中经过测试和运行,如果您对数据库性能或任何事情有任何建议/批评,请做,我愿意接受建议和讨论