douchuo1963 2018-02-26 17: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-26 18: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.

    展开全部

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

报告相同问题?

手机看
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回
顶部