【问题标题】:Advices to implement child comments on comments (How to set it up)对评论实施子评论的建议(如何设置)
【发布时间】:2019-12-25 17:33:55
【问题描述】:

我正在使用 Laravel,并使用 laravel 创建了一个可变形的评论表。现在我想实现回复功能,以便人们可以回复 cmets。我只需要第一级的回答。因此,您可以回答评论,但不能回答评论孩子。 Facebook 上只有一级评论孩子,而不是 2 或 3 级。

我现在向您提出的问题是,这是解决此问题的最佳方法。因为在我的 laravel 视图刀片中,我正在循环浏览每条评论,并希望在这条评论上打印我的孩子 cmets(我只是不知道如何处理他的?)。

所以基本上,我想知道您将如何设计表格,如何映射它以及如何在视图中打印它。

到目前为止,这是我的桌子:

CREATE TABLE `comments` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `commentable_type` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  `commentable_id` bigint(20) unsigned NOT NULL,
  `user_id` bigint(20) unsigned NOT NULL,
  `post_status_id` bigint(20) unsigned NOT NULL DEFAULT '4',
  `content` text COLLATE utf8mb4_unicode_ci NOT NULL,
  `created_at` timestamp NULL DEFAULT NULL,
  `updated_at` timestamp NULL DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `comments_commentable_type_commentable_id_index` (`commentable_type`,`commentable_id`),
  KEY `comments_user_id_index` (`user_id`),
  KEY `comments_post_status_id_index` (`post_status_id`),
  CONSTRAINT `comments_post_status_id_foreign` FOREIGN KEY (`post_status_id`) REFERENCES `post_statuses` (`id`) ON DELETE CASCADE,
  CONSTRAINT `comments_user_id_foreign` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=34 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

【问题讨论】:

标签: php mysql sql laravel eloquent


【解决方案1】:

实际上,如果您只想“一级回答”,则只需两张桌子。

第一个是“comment_answer”,包含 cmets 和答案。 cmets 和 answers 不需要额外的表格,因为每个评论都有一个答案,不是吗?因此,我们可以将每个答案与其相关的问题保存在同一记录中。像这样迁移;

 Schema::create('comment_answer', function (Blueprint $table) {
        $table->increments('id');
        $table->longText('content');
        $table->longText('answer')->nullable();
        $table->boolean('is_publish')->default(0);
        $table->timestamps();
    });

我以简单的形式添加了列,您可以根据自己的项目添加..

第二个是“post_comment_user”,用于包含帖子和用户与 cmets 和答案的关系。像这样迁移

Schema::create('post_comment_user', function (Blueprint $table) {
        $table->increments('id');
        $table->integer('post_id')->unsigned();
        $table->integer('comment_id')->unsigned();
        $table->integer('user_id')->unsigned();

        $table->foreign('post_id')->references('id')->on('posts')->onDelete('cascade');
        $table->foreign('comment_id')->references('id')->on('comment_answer')->onDelete('cascade');
        $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');

    });

我已经简单地建立了关系,如果你愿意,你也可以为用户使用“comment_answer”表

然后,您可以像这样在模型文件('post')中为帖子带来 cmets;

public function get_comments(){
    return $this->belongsToMany('App\Models\comment_answer',
        'post_comment_user',
        'post_id',
        'comment_id')
        ->where('is_publish',1)
        ->orderBy('created_at');

和这样的控制器;

$posts=post::where('slug',$post_slug)
        ->with('get_comments')
        ->where('is_publish',1)
        ->firstOrFail();

和这样的刀片文件;

@foreach($posts->get_comments as $comment)
      {{$comment->content}}
      {{$comment->answer}}
@endforeach

【讨论】:

  • 尽量使关系名称易于理解和有意义。与其使用 get_cmets,不如简单地称其为 cmets。想象一下 Post::with('get_cmets') 而不是 Post::with('cmets')
  • @iJamesPHP2 好的,知道了。非常感谢。
【解决方案2】:

子 cmets 应该只是更多 cmets,除非它们被映射到另一个评论。

创建一个comment_children 表。

结构应该是:

id:大整数 comment_id:大整数 child_id: BIGINT

然后你可以在你的 Comment 模型上创建一个 hasManyThrough 子关系,并使用 comment_children 表来匹配它们。

这将允许您预先加载子 cmets,您可以通过添加使您的模式始终执行此操作:

protected $with = [‘children’]

您还需要在 PostStatus 模型上建立 cmets 关系。

设置您的模型以始终加载此关系,还可以添加:

protected $with = [‘comments’]

现在,每当您获取帖子时,该集合将始终包含所有 cmets 和所有子项。

现在访问它,类似于:

$post = Post::where(‘id’, 1)->first()

在你的刀片中:

@foreach($post->comments as $comment)
    // display comment
    @foreach($comment->children as $child)
        // display child comments
    @endforeach
@endforeach

【讨论】:

  • 您能否将智能引号 替换为常规引号,例如 '?如果有人访问该问题并使用您的答案并如图所示复制它,它将引发解析错误。如果他们不知道如何做到这一点,那么您的答案对他们将不起作用。
  • @FunkFortyNiner 这个答案是为了建议,它的任何内容都不能被复制。我的手机输入了这些引号,道歉
  • “所有内容都不可复制” - 为什么?复制/粘贴经常使用。我怀疑有人会重新输入而不是复制。
  • @FunkFortyNiner 他们为什么还要重新输入?这是一个解决方案的大纲。为什么堆栈溢出的人都喜欢按照你的方式行事,这很奇怪。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-30
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-07
相关资源
最近更新 更多