Laravel:基于子表值显示父值

Laravel:基于子表值显示父值,laravel,reflection,Laravel,Reflection,在我的laravel应用程序中,我面临一种需要以网格格式显示记录列表的情况。但是,其中一列名为read,它取决于子表的记录数 表格: comments: id, user_id, comment, post_date comment_replies: id, comment_id, reply, is_read (default false) 如果comment\u repress表的已读列至少有一个false值,则网格列已读必须为未读否则“已读”受尊重的记录 我的当前代码

在我的laravel应用程序中,我面临一种需要以网格格式显示记录列表的情况。但是,其中一列名为
read
,它取决于子表的记录数

表格:

comments:
    id, user_id, comment, post_date

comment_replies:
    id, comment_id, reply, is_read (default false)
如果
comment\u repress
表的
已读
列至少有一个
false
值,则网格列
已读
必须为
未读
否则“已读”受尊重的记录

我的当前代码

class Comment extends Model
{
    public function index()
    {
        # fetching data
        $modelSelf = self::select([
            "comments.id",
            "comments.user_id",
            "comments.comment",
            "comments.post_date"
        ])
        ->paginate(15)
        ->map(function($comment) {
            $comment->read = ($comment->reply->where('is_read', false)->count() > 0)
                ? 'Unread'
                : 'Read';

            return $comment;
        });

        # return
        return !($modelSelf->isEmpty())
            ? $modelSelf
            : null;
    }
}
我是用正确的方法做的,还是有更好的方法做的?

这可以通过关系来完成吗?

这会让你开始。您可以使用雄辩的模型和关系来执行所有数据访问逻辑,然后可以在PHP层中操作集合上的
read

class Comment extends Model
{
    public function replies()
    {
        return $this->hasMany(Reply::class);
    }
}

class Reply extends Model
{
    public function reply()
    {
        return $this->belongsTo(Comment::class);
    }
}

class CommentController
{
    public function index()
    {
        $comments = Comment::with('replies')->get()
            ->map(function($comment) {
                $comment->read = $comment->replies->pluck('is_read')->filter(function($reply) {
                    // This will leave only replies that are false
                    return ! $reply;
                })
                return $comment;
            });

        // You could do a return view('comments', compact('comments)); here to return the comments to a blade file for output
        return $comments;
    }
}
正如@muhammad dyas yaskur指出的,您可以在comment模型上设置
read
属性,以避免像我所做的那样在控制器中这样做。 有关详细信息,请参见文档:

免责声明 实际上,我还没有测试设置
read
属性的逻辑。它可能不是第一次起作用,但基本概念会让你朝着正确的方向前进

设置
read
属性的更好方法可能是:

$comment->read = (bool) $comment->replies->where('is_read', false)->count();
我也可能会让你的真/假在
$comment->read
属性中出现错误。您可以通过插入感叹号来切换:

$comment->read = (bool) ! $comment->replies->where('is_read', false)->count();

有趣的是,您的索引方法似乎位于
注释
模型上。这与拉威尔的MVC理念背道而驰,在这里可能与你作对。我知道你有一个评论模型和一个回复模型。你可以利用有说服力的关系来解决你的问题。你应该用有说服力的关系来代替这个查询。示例
setReadAttribute
此代码反映了我的实际代码。但情况是真实的。我也试图通过人际关系做到这一点,但没有成功。你能写一个示例代码吗?谢谢@jonwhite,它可以工作了。但是,如果我使用的是
paginate
而不是
get
,那么它就不起作用。如何解决这个问题?我可能需要看一个例子。你能给你原来的帖子加个更新吗?我假设您正在将每个集合的结果数传递给paginate函数?您是在与get()调用相同的位置调用paginate,还是在回复集合中调用paginate?亲爱的@jonwhite,我已经更新了问题,请查看。我还建立了模型中的关系。这样,使用
paginate
函数可以删除分页参数,而只返回带有获取值的数据数组。正如我所需要的,其余的工作绝对正常。