如何在Laravel Eloquent多态关联中添加user_id字段?
解决多态评论关联中存入user_id的问题
我来帮你一步步搞定这个问题,核心就是在评论模型和用户模型间建立关联,再在创建评论时正确传递当前登录用户的ID即可:
1. 确保comments表拥有user_id字段
如果还没给comments表添加user_id字段,先创建一个迁移来完成这件事:
php artisan make:migration add_user_id_to_comments_table --table=comments
打开生成的迁移文件,添加外键字段:
public function up() { Schema::table('comments', function (Blueprint $table) { $table->foreignId('user_id')->constrained()->onDelete('cascade'); }); } public function down() { Schema::table('comments', function (Blueprint $table) { $table->dropForeign(['user_id']); $table->dropColumn('user_id'); }); }
最后执行迁移:
php artisan migrate
2. 配置模型关联
在Comment模型里,除了你已经配置好的多态关联,还要添加和User的关联,同时把user_id加入可填充字段:
namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Database\Eloquent\Relations\MorphTo; class Comment extends Model { // 确保user_id在批量赋值白名单里 protected $fillable = ['content', 'user_id']; // 你已有的多态关联 public function commentable(): MorphTo { return $this->morphTo(); } // 新增与用户的关联 public function user(): BelongsTo { return $this->belongsTo(User::class); } }
可选:在User模型里添加反向关联,方便后续获取用户的所有评论:
public function comments(): HasMany { return $this->hasMany(Comment::class); }
3. 用Eloquent存入user_id
这里提供三种常用的实现方式,你可以根据场景选择:
方式一:控制器手动赋值(最直观)
在处理评论提交的控制器方法里,直接获取当前登录用户ID并赋值:
public function storeComment(Request $request, Post $post) { $request->validate([ 'content' => 'required|string', ]); $post->comments()->create([ 'content' => $request->content, 'user_id' => auth()->id(), // 直接传入当前登录用户ID ]); return back(); }
方式二:通过用户关联创建(自动填充user_id)
借助用户模型的关联来创建评论,此时user_id会被自动填充:
auth()->user()->comments()->create([ 'content' => $request->content, 'commentable_id' => $post->id, 'commentable_type' => Post::class, ]);
方式三:模型事件自动填充(最优雅)
如果希望所有评论都自动关联当前登录用户,可以在Comment模型里注册creating事件:
protected static function booted() { static::creating(function (Comment $comment) { // 仅当用户登录时才赋值,避免未登录场景报错 if (auth()->check()) { $comment->user_id = auth()->id(); } }); }
之后创建评论时,只需要传入内容和多态关联字段即可,user_id会自动填充:
$post->comments()->create([ 'content' => $request->content, ]);
注意事项
- 一定要确保
user_id在Comment模型的$fillable数组里,否则会触发Eloquent的批量赋值保护,导致字段无法写入。 - 如果你的应用允许未登录用户评论,记得在代码里增加判断逻辑,避免
auth()->id()返回null引发数据库报错。
内容的提问来源于stack exchange,提问作者Tom Headifen
相关产品推荐
相关产品推荐

