douchuo1963 2018-02-27 01:54
浏览 59
已采纳

HasMany对象还是Eloquent:哪个更好?

I have the following controller for blog

public function show($slug)
{
    $post = Blog::where('slugs', '=', $slug)->first();

    $vars['pageTitle'] = Config::get('site.pageTitle') . $post['title'];

    // The breadcrumbs... needs to be repopulated every page
    $vars['breadCrumbs'] = [[
        'url'   => action('SimpleController@index'),
        'title' => 'CovertDEV'
    ],[
        'url'   => action('BlogController@index'),
        'title' => 'Blog'
    ],[
        'url'   => route('blog_post', ['slug' => $slug]),
        'title' => $post['title']
    ]];

    $vars['blog'] = $post;

    // The following line is what the question is about
    $vars['comments'] = $post->Blog_comments->groupBy('comment_id');

    return view('blog', $vars);
}

My model for blogs originally looked like

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog extends Model
{
    //

    public function tags()
    {
        return $this->belongsToMany('App\Tag');
    }

    public function blog_comments()
    {
        return $this->hasMany('App\Blog_comment');
    }

    public function users()
    {
        return $this->belongsTo('App\User', 'user_id');
    }
}

and for blog_comments

namespace App;

use Illuminate\Database\Eloquent\Model;

class Blog_comment extends Model
{
    //

    public function users()
    {
        return $this->belongsTo('App\User', 'user_id');
    }

    public function blogs()
    {
        return $this->belongsTo('App\Blog');
    }

}

I'm retrieving the comments for the post and displaying it on the page. Everything is working perfectly... but then I tried to use my relationship instead... (that changes that line to...)

$vars['comments'] = $post->blog_comments()->get()->groupBy('comment_id');

And that works just as well. My post isn't big, just a simple 'Lorem Ipsum' test text and 7 comments to test the feature so I don't see any difference in load times between the two methods.

Or are they both the same way? The previous way looks better, but I'm not sure if I'm implementing the ORM as intended, if not then which way is better?

But I'm new to Laravel (this is my first framework) so I don't know... which way is better/faster/more efficient? Maybe there's an even better/more efficient way to accomplish this that I don't know of yet.

Sorry if this seems obvious. I want to get this out of the way before continuing on the project... don't want to be redoing everything after finding out a better way to tie pieces of information together.

Thanks in advance!

My Database Dump Is

CREATE TABLE `blog_comments` (
  `id` int(10) UNSIGNED NOT NULL,
  `user_id` int(10) UNSIGNED NOT NULL,
  `blog_id` int(10) UNSIGNED NOT NULL,
  `comment_id` int(11) NOT NULL DEFAULT '0',
  `comment` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `likes` int(11) NOT NULL DEFAULT '0',
  `deleted_at` timestamp NULL DEFAULT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

--
-- Dumping data for table `blog_comments`
--

INSERT INTO `blog_comments` (`id`, `user_id`, `blog_id`, `comment_id`, `comment`, `likes`, `deleted_at`, `created_at`, `updated_at`) VALUES
(1, 1, 2, 0, 'Interesting post. Very well structured and good points throughout! One question though, Enim blandit volutpat maecenas volutpat blandit aliquam etiam erat velit?', 0, NULL, '2018-02-24 20:31:45', '2018-02-24 20:31:45'),
(2, 2, 2, 1, 'Thank you, very interesting question. Unique point of view. Semper viverra nam libero justo. Sit amet commodo nulla facilisi. Blandit massa enim nec dui nunc. Eget velit aliquet sagittis id consectetur purus ut faucibus.', 0, NULL, '2018-02-25 02:26:32', '2018-02-25 02:26:32'),
(3, 1, 2, 1, 'Indeed! I can now finally lorem ipsum by myself all the way commodo nulla facilisi!', 0, NULL, '2018-02-25 04:36:18', '2018-02-25 04:36:18'),
(4, 2, 2, 0, 'Weird, I thought I had more information posted. Must have being moderated out of existence then.', 0, NULL, '2018-02-25 09:18:58', '2018-02-25 09:18:58'),
(5, 1, 2, 4, 'Sorry about that, you had quite a few needless stuff in there. Had to tweak your post a bit. Otherwise, everything is lorem ipsum!', 0, NULL, '2018-02-25 12:53:18', '2018-02-25 12:53:18'),
(6, 2, 2, 3, 'Glad that it works for you!', 0, NULL, '2018-02-26 05:35:46', '2018-02-26 05:35:46'),
(7, 1, 2, 6, 'Thank you, feels good!', 0, NULL, '2018-02-25 07:08:33', '2018-02-25 07:08:33');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `blog_comments`
--
ALTER TABLE `blog_comments`
  ADD PRIMARY KEY (`id`),
  ADD KEY `blog_comments_user_id_index` (`user_id`),
  ADD KEY `blog_comments_blog_id_index` (`blog_id`);

I need the outcome array to look the following:

Array
(
    [comment_id] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [user_id] => 1
                    [blog_id] => 2
                    [comment_id] => 0
                    [comment] => Interesting post. Very well structured and good points throughout! One question though, Enim blandit volutpat maecenas volutpat blandit aliquam etiam erat velit?
                    [likes] => 0
                    [deleted_at] => 
                    [created_at] => 2018-02-24 14:31:45
                    [updated_at] => 2018-02-24 14:31:45
                )

            [1] => Array
                (
                    [id] => 4
                    [user_id] => 2
                    [blog_id] => 2
                    [comment_id] => 0
                    [comment] => Weird, I thought I had more information posted. Must have being moderated out of existence then.
                    [likes] => 0
                    [deleted_at] => 
                    [created_at] => 2018-02-25 03:18:58
                    [updated_at] => 2018-02-25 03:18:58
                )
        )
)

comment_id is the same thing as parent_id... I originally named it comment_id now I don't feel like changing it.

Any comment with comment_id of 0 are parent comments, any comment with comment_if of any number, they are a child of that comment.

Might have caused some confusion. Sorry about that.

I just want to know what is the most efficient way of generating this kind of an array. I've went through 3 or 4 methods and now I'm wondering if I missed something.

  • 写回答

1条回答 默认 最新

  • douqi3913 2018-02-27 02:13
    关注

    I think this is a not so clean but I believe a more efficient solution than depending on Collection's groupBy

    $post = Blog::with(['blog_comments' => function($query) {
        $query->groupBy('comment_id');
    }])->where('slugs', $slug)->first();
    
    $vars['comments'] = $post->blog_comments;
    

    Although if you do not expect thousands of comments, your current implementation is okay.

    Using this is more efficient because you're giving the groupBy workload to the database manager rather than to php itself (when using Collection's groupBy).

    You may also declare another relationship that will suit your grouping needs.

    // Blog.php
    public function groupedBlogComments()
    {
        return $this->hasMany(BlogComment::class)
                    ->groupBy('comment_id');
    
        // I think this can be `return $this->blogComments()
        //                                  ->groupBy('comment_id');
    }
    
    // you can still have this, if ever you do not want grouped comments
    public function blogComments()
    {
        return $this->hasMany(BlogComment::class);
    }
    
    // Controller
    $vars['comments'] = $post->groupedBlogComments;
    

    Or even better, define a scope in your BlogComment model, and use that anywhere.

    // BlogComment.php
    public function scopeGroupByCommentId($query)
    {
        return $query->groupBy('comment_id');
    }
    
    // You can eager load your relationships and use the scope.
    $post = Blog::with(['blog_comments' => function($query) {
        $query->groupByCommentId();
    }])->where('slugs', $slug)->first();
    
    $vars['comments'] = $post->blog_comments;
    

    If there are any mistakes, please don't hesitate to correct me.

    I hope I got your point.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何绘制动力学系统的相图
  • ¥15 对接wps接口实现获取元数据
  • ¥20 给自己本科IT专业毕业的妹m找个实习工作
  • ¥15 用友U8:向一个无法连接的网络尝试了一个套接字操作,如何解决?
  • ¥30 我的代码按理说完成了模型的搭建、训练、验证测试等工作(标签-网络|关键词-变化检测)
  • ¥50 mac mini外接显示器 画质字体模糊
  • ¥15 TLS1.2协议通信解密
  • ¥40 图书信息管理系统程序编写
  • ¥20 Qcustomplot缩小曲线形状问题
  • ¥15 企业资源规划ERP沙盘模拟