0

我有 3 个模型(用户、帖子和评论)。

用户型号:

public function posts() // A user can have many posts
{
    return $this->hasMany('App\Post', 'from_id');
}

岗位型号:

protected $with = [ // I'm using with() here
    'from',
    'for',
    'comments',
];

public function from() // Post owner
{
    return $this->belongsTo(User::class, 'from_id');
}

public function for() // To whom this post is addressed
{
    return $this->belongsTo(User::class, 'for_id');
}

public function comments() // All comments for this post
{
    return $this->morphMany(Comment::class, 'commentable');
}

迁移后:

$table->id();

$table->string('uuid');

$table->foreign('from_id')->references('id')->on('users');
$table->unsignedBigInteger('from_id');
        
$table->foreign('for_id')->references('id')->on('users');
$table->unsignedBigInteger('for_id')->nullable();

$table->text('body');

$table->timestamps();
$table->softDeletes();

评论型号:

protected $with = [ // I'm also using with() here
    'from',
    'children',
];

public function from() // Comment owner
{
    return $this->belongsTo(User::class, 'from_id', 'id');
}

public function commentable()
{
    return $this->morphTo();
}

public function children() // child comments for this comment (?) Not sure how it's working or not
{
    return $this->hasMany(Comment::class, 'parent_id');
}

评论迁移:

$table->id();

$table->string('uuid');

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

$table->foreign('from_id')->references('id')->on('users');
$table->unsignedBigInteger('from_id');

$table->foreign('parent_id')->references('id')->on('comments');
$table->unsignedBigInteger('parent_id')->nullable();

$table->text('body');
        
$table->timestamps();
$table->softDeletes();

请注意,我的用户表中有两个虚拟用户。

然后假设我们的 Posts 表中有两条记录:

|------------------------------------------------------|
|  id  |  uuid  |  from_id  |  for_id  |  body  | ...  |
|------------------------------------------------------|
|  1   |  ....  |  1        |  null    |  ...   | ...  |  
|  2   |  ....  |  1        |  null    |  ...   | ...  |

所以让我们为 id #1 创建一个注释:

php artisan tinker
>> $post = App\Post::first();
>> $post->comments()->create(['from_id' => 2, 'body' => 'Test comment']);
>> App\Comment {#3744
       from_id: 2,
       body: "Test comment",
       commentable_id: 1,
       commentable_type: "App\Post",
       uuid: "68bc8dbd-9769-44d7-8139-3e4e14d3df4f",
       updated_at: "2020-09-01 15:00:38",
       created_at: "2020-09-01 15:00:38",
       id: 1,
  }

现在让我们看看第一个带有评论的帖子(我$with在我的 Post 模型中使用 protected):

php artisan tinker
>> $post = App\Post::first();
>> App\Post {#4030
       id: 1,
       uuid: "e9503551-99ac-495f-902e-b505408ab9ef",
       from_id: 1,
       for_id: null,
       body: "Vero vel officia qui et. Veritatis laudantium itaque nisi sint repellendus laborum. Nihil at aliquam alias in.",
       created_at: "2020-09-01 14:59:11",
       updated_at: "2020-09-01 14:59:11",
       deleted_at: null,
       comments: Illuminate\Database\Eloquent\Collection {#4039
           all: [
               App\Comment {#4049
                   id: 1,
                   uuid: "68bc8dbd-9769-44d7-8139-3e4e14d3df4f",
                   commentable_id: 1,
                   commentable_type: "App\Post",
                   from_id: 2,
                   parent_id: null,
                   body: "Test comment",
                   created_at: "2020-09-01 15:00:38",
                   updated_at: "2020-09-01 15:00:38",
                   deleted_at: null,
                   from: App\User {#4061
                       id: 2,
                       name: "Prof. Runte Jr.
                       email: "abigail@example.test",
                       ...
                   },
                   children: Illuminate\Database\Eloquent\Collection {#4040
                       all: [],
                   },
               },
           ],
       },
   }

我们可以看到第一个帖子现在有评论了,好吧。

现在我想为之前帖子中的第一条评论创建一个子评论:

php artisan tinker

// get the first post, and then get the first comment of it
>> $post = App\Post::first()->comments()->first();

>> App\Comment {#4060
       id: 1,
       uuid: "68bc8dbd-9769-44d7-8139-3e4e14d3df4f",
       commentable_id: 1,
       commentable_type: "App\Post",
       from_id: 2,
       parent_id: null,
       body: "Test comment",
       created_at: "2020-09-01 15:00:38",
       updated_at: "2020-09-01 15:00:38",
       deleted_at: null,
       from: App\User {#4073
           id: 2,
           name: "Prof. Runte Jr.
           email: "abigail@example.test",
           ...
       },
       children: Illuminate\Database\Eloquent\Collection {#4030
           all: [],
       },
   }

// Now we want to create child comment

// Get the first post
>>  $post = App\Post::first()
// Get the first comment from it
    ->comments()->first()
// Get children relationship (IDK if this the right words to put it) and create a child comment
    ->children()->create(['from_id' => 1, 'body' => 'Testing child comment']);

这是修补程序返回的内容:

Illuminate/Database/QueryException with message 'SQLSTATE[HY000]: General error: 1364 Field 'commentable_id' doesn't have a default value (SQL: insert into comments( from_id, body, parent_id, uuid, updated_at, created_at) values (1, Testing child comment, 1, aa3d624f-3984-438c-adb0-26086459de33, 2020-09-01 15:38:36, 2020-09-01 15:38:36))'

所以我的问题是:

如何在多态关系(morphMany())中进行子评论?我已经设置了parent_id属于评论 ID 的列。

4

1 回答 1

0

作为comments()评论的返回集合。所以,你应该像这样使用这个:

$post = App\Post::first();
foreach($post->comments() as $comment){
  $comment->children()->create([
     'from_id' => 1, 
     'body' => 'Testing child comment'
  ]);
}

您还可以将save()方法用作:

$post = App\Post::first();

$comment = new App\Comment([
  'from_id' => 1, 
  'body' => 'Testing child comment'
]);

$child = $post->comments()->first()->save($comment);

你必须改变你的App\Comment方法children()

public function children()
{
    return $this->morphMany(Comment::class, 'commentable');
}
于 2020-09-01T08:39:17.560 回答