Laravel 5.5如何设置关联中间表(pivot)的额外字段值?
搞定Laravel中间表post_tag额外字段赋值的问题
嘿,作为Laravel新手碰到中间表额外字段的问题太正常了,我来给你捋清楚怎么设置uuid和app_uuid这两个字段的值~
首先,先把你的Post和Tag模型的关联配置调整好,得让Laravel知道中间表还有这些额外字段要处理:
// app/Models/Post.php public function tags() { return $this->belongsToMany(Tag::class, 'post_tag') ->withPivot('uuid', 'app_uuid', 'created_at', 'updated_at'); } // app/Models/Tag.php public function posts() { return $this->belongsToMany(Post::class, 'post_tag') ->withPivot('uuid', 'app_uuid', 'created_at', 'updated_at'); }
接下来分两种常见场景来操作:
场景1:给已有文章关联标签时赋值
如果你已经有了Post实例,现在要给它关联Tag,同时设置中间表的字段,直接用attach()方法就行,把额外字段放进第二个参数的数组里:
// 假设你已经拿到了$post实例,$tagIds是要关联的标签ID数组 $post->tags()->attach($tagIds, [ 'uuid' => uuid(), // 直接调用你的uuid()函数 'app_uuid' => $request->app_uuid, 'created_at' => now(), // 用Carbon的now()生成时间,你的Schema没设默认值,得手动传 'updated_at' => now() ]);
场景2:创建新文章同时关联标签并赋值
如果是刚创建Post就要关联Tag,步骤也很简单:
// 先创建Post,这里假设你只需要存标题和内容,根据你的实际字段调整 $post = Post::create($request->only(['title', 'content'])); // 紧接着关联标签并设置中间表字段 $post->tags()->attach($request->tag_ids, [ 'uuid' => uuid(), 'app_uuid' => $request->app_uuid, 'created_at' => now(), 'updated_at' => now() ]);
进阶玩法:自动处理uuid和时间字段
要是不想每次关联都手动写uuid和时间字段,可以给中间表建个模型,用观察者自动赋值,省不少事:
第一步:创建中间表模型
// app/Models/PostTag.php namespace App\Models; use Illuminate\Database\Eloquent\Model; class PostTag extends Model { protected $table = 'post_tag'; public $timestamps = false; // 因为我们要自己处理时间字段,或者你也可以让Laravel自动处理,调整下字段配置就行 }
第二步:写观察者类
// app/Observers/PostTagObserver.php namespace App\Observers; use App\Models\PostTag; class PostTagObserver { // 创建记录时自动赋值 public function creating(PostTag $postTag) { $postTag->uuid = uuid(); $postTag->created_at = now(); $postTag->updated_at = now(); } // 更新记录时自动更新时间 public function updating(PostTag $postTag) { $postTag->updated_at = now(); } }
第三步:注册观察者
打开AppServiceProvider,在boot()方法里注册这个观察者:
// app/Providers/AppServiceProvider.php use App\Models\PostTag; use App\Observers\PostTagObserver; public function boot() { PostTag::observe(PostTagObserver::class); }
这样之后,再关联的时候就只需要传app_uuid了,剩下的字段会自动处理:
$post->tags()->attach($tagIds, [ 'app_uuid' => $request->app_uuid ]);
最后提个小建议:你的Schema里created_at没设默认值,要么每次手动传,要么改Schema的时候加个->default(DB::raw('CURRENT_TIMESTAMP')),让数据库自动生成,这样更省心~
内容的提问来源于stack exchange,提问作者deyaamuhammad
相关产品推荐
相关产品推荐

