laravel 8 -> 为具有多态关系的 post 添加评论和回复

laravel 8 ->add comment and replies for post with polymorphic relation

我正在用 laravel 8 构建 API 并想为具有多态关系的 post 添加评论和回复(因为我有 postsanalysis 他们有评论。)

所以我创建了我的 tables。我的 post table :

        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('category_id');
            $table->unsignedBigInteger('user_id');

            $table->string('title');
            $table->longText('body');
            $table->longText('picture');
            $table->string('study_time');
            $table->integer('likes')->nullable();
            $table->tinyInteger('status')->nullable()->comment('status is 1 when a post is active and it is 0 otherwise.')->nullable();
            $table->text('tags')->nullable();


            $table->foreign('category_id')->references('id')->on('categories');
            $table->foreign('user_id')->references('id')->on('users');

和我的评论 table :


        Schema::create('comments', function (Blueprint $table) {
            $table->id();

            $table->integer('commentable_id');
            $table->string('commentable_type');

            $table->unsignedBigInteger('parent_id')->nullable(); //nullable for comments , with value for replies
            $table->string('name' , 45);
            $table->string('email');
            $table->longText('comment');
            $table->integer('like')->nullable();
            $table->integer('dislike')->nullable();

            $table->foreign('parent_id')->references('id')->on('posts')->onUpdate('cascade')->onDelete('cascade');

如您所见,我不需要身份验证即可发表评论。 所以我的 post 模型有这样的关系:

 public function comments()
    {

        return $this->morphMany(Comment::class, 'commentable' )->whereNull('parent_id');
    }

和评论模型:


   public function commentable(){

       return $this->morphTo();
       
   }

   public function replies()
   {
       return $this->hasMany(Comment::class, 'parent_id');
   }

然后我为 CRUD 评论创建了一个 CommentController,并在我的存储方法中放置了这段代码以添加新评论:

public function store(Request $request)
    {

        $comment = new Comment;

        $comment->name = $request->name;
        $comment->email = $request->email;
        $comment->comment = $request->comment;

        $post = Post::find($request->post_id);

        $post->comments()->save($comment);

        return response()->json($comment);

    }

当我在 postman 中发送请求时,出现此错误:Error: Call to a member function comments() on null

我知道它用于 post_id 但我不知道如何更改它,我是初学者并且我对 laravel 中的多态性了解不多,只是使用了这个 link 用于创建评论: https://appdividend.com/2018/06/20/create-comment-nesting-in-laravel/

你能告诉我我的错误在哪里吗?非常感谢

已编辑:

$data = $request->all();
        $validator = Validator::make($data, [
            'name'=>'required',
            'email' => 'required',
            'comment'=>'required',
            'post_id'=>'required|exists:posts,id'
        ]);

        $post = Post::find($request->post_id);


        if ($validator->fails()) {
            return response()->json(['error' => $validator->errors(), 'Validation Error']);
        }

        $post->comments()->save($data);

        return response()->json($post);

为什么给我这个错误? : TypeError: Argument 1 passed to Illuminate\Database\Eloquent\Relations\HasOneOrMany::save() must be an instance of Illuminate\Database\Eloquent\Model, array given

嗯,你只需要为 post id 添加一个验证规则,它应该是 'required' 和 'exist':

 $validator = Validator::make($data, [
            'name'=>'required',
            'email' => 'required',
            'comment'=>'required',
            'post_id' => 'required|exists:posts,id'
        ]);
// make sure that post table name is 'posts' and the id column name  is 'id',
// or changed according to your db ..

  $post = Post::find($request->post_id);

现在您保证 $request->post_id 将是有效输入。

现在您可以保存该评论了:

$comment= new Comment($data);
 $post->comments()->save($comment);