【问题标题】:Threaded Comments in Laravel w/Eloquent带有 Eloquent 的 Laravel 中的线程注释
【发布时间】:2014-11-20 04:20:01
【问题描述】:

我有允许用户互相留言的用户配置文件。 (想想 Facebook/MySpace)...

给定一个profile_messages 表,其中包含以下字段iduser_idauthor_idparent_idmessage,我将如何在线程布局中有效地显示它们?

注意:cmets 将只有 1 级深度。

目前,我正在获取所有相关的 cmets,然后重建集合以在每个项目上具有 $messagesreplies 的子集合。

$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


这很好用。但是,我不禁想到有更好的方法来做到这一点......有没有更好的方法来做到这一点,或者也许有一种方法可以利用关系来获得与$profileMessage->replies 匹配的结果集结构?

【问题讨论】:

    标签: php laravel eloquent threaded-comments


    【解决方案1】:

    根据您的描述,我假设您有根消息,其中 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');
    }
    

    【讨论】:

    • 谢谢,我在想一些类似的事情,但一直遇到 +1 问题,所以我知道我做的不对。我会试一试,看看它是否是我正在寻找的。 :)
    • 使用 n+1 进行紧急加载以进行救援。是的,这就是你要找的:)
    • 嗯,无论我如何尝试加载它们,我仍然遇到 n+1 问题...我已经在此处发布了根据您的代码所做的更改:laravel.io/bin/xK0WB
    • 好吧,不,你没有遇到 n+1 问题;)你只是在那里加载了太多东西,但我不会担心。 n+1 意味着您对每个条目都运行一个查询,但这里不是这种情况。您只有 user 关系和 author 关系引用同一个 User,但它仍然需要 2 个查询。就像在我的回答中一样 - 我想您不需要在 replies 上加载 user 关系,因为它们指的是另一条消息,而不是用户本人,对吧?
    • 啊,你说得对,用户是多余的。但是,似乎我试图在视图中访问 $message->replies 是在 Eloquent 尝试在集合中不存在它们时获取它们。这就是最后两个 select * from profile_messages 查询的来源......
    猜你喜欢
    • 2015-12-17
    • 1970-01-01
    • 2017-07-11
    • 2019-09-16
    • 1970-01-01
    • 2011-07-04
    • 2014-12-21
    • 1970-01-01
    • 2018-03-20
    相关资源
    最近更新 更多