在$ user-> posts()-> create([...])期间使用mutator的laravel访问相关模型 [英] laravel access related model using mutator during $user->posts()->create([...])
问题描述
我有User和Post模型.在创建帖子时调用帖子标题的变体时,希望访问用户.类似于几年前的问题.
I have User and Post models. Would like to access the User when the mutator for the post's title is being called at the time of the post creation. Similar to a question from a few years ago.
但是我无法在帖子"标题更改器中访问用户".尝试过 $ this-> user-> id
(首选).还尝试过: $ this-> user_id
, $ this-> user()-> get()-> id
.
But I am unable to access the User inside the Posts title mutator.
Tried $this->user->id
(preferred). Also tried: $this->user_id
, $this->user()->get()->id
.
>>> User::first()->posts()->create(['title'=>'test '.now()])
PHP Warning: Attempt to read property "id" on null <<<=== when trying $this->user->id
=> App\Models\Post {#4155
title: "test 2021-05-08 11:41:55", <<<=== title is shown before user_id
user_id: 1, <<<=== but in migration user_id is defined *before* title
updated_at: "2021-05-08 11:41:55",
created_at: "2021-05-08 11:41:55",
id: 1,
user: null, <<<=== note "user" attribute is added as result of the $this->user->id
}
当我们正在使用该用户向其添加帖子时,会认为该用户当时肯定是已知的.
Would think the user is definitely known at that time, as we're using that user to add a post to.
如果我将 user_id
设为可填充,则该代码将按预期工作(对于该代码:数组顺序很重要):
If I make the user_id
fillable, then this one works as expected (for that one: the array order matters):
Post::create(['user_id'=>User::first()->id, 'title'=>'test '.now()])
但是,这没那么...雄辩.
But, that's less... eloquent.
我的配置+测试详细信息:
My config + test details:
// Post.model
protected $fillable = [
// 'user_id', // also tried with making user_id fillable
'title',
];
public function setTitleAttribute($value) {
// dump($this->user_id); // null
// dump($this->user); // null (& adds empty user property to this)
// dump($this->user->id); // PHP Warning: Attempt to read property "id" on null (& adds property)
// dump($this->user()->get()); // empty collection Illuminate\Database\Eloquent\Collection
// dump($this->user()->toSql()); // select * from "users" where "users"."id" is null
$this->attributes['title'] = $value;
}
public function user() {
return $this->belongsTo(User::class);
}
// User.model
public function posts() {
return $this->hasMany(Post::class);
}
// posts migration
Schema::create('posts', function (Blueprint $table) {
$table->id();
$table->foreignId('user_id')->constrained();
$table->string('title');
$table->timestamps();
});
使用mysql作为数据库.
Using mysql as DB.
推荐答案
这似乎是最安全+最干净的:使用引导事件关闭正在创建" ,该操作在更改器之后且就在数据保存到数据库之前触发.
This seems to be the safest + cleanest: use boot event closure 'creating', which is triggered after the mutators and right before data is saved to the database.
public static function boot() {
parent::boot();
static::creating(function (Post $post) {
// now we have both $post->user and $post->title
dump($post->user->name);
dump($post->title);
});
}
这篇关于在$ user-> posts()-> create([...])期间使用mutator的laravel访问相关模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!