您可以使用Laravel's accessors and mutators 解决此问题。
在这个例子中,我只会从UserDetail 添加gender,因为我很懒。因此,我们首先在 User 模型中添加性别访问器
public function details()
{
return $this->hasOne(UserDetail::class);
}
public function getGenderAttribute()
{
return $this->details->gender ?? null;
}
此 getter 将从详细信息中获取性别,如果不存在详细信息,则为 null。
现在我们在 Nova 中的 User 资源中添加一个新字段。
public function fields(Request $request)
{
return [
ID::make()->sortable(),
Gravatar::make(),
Text::make('Name')
->sortable()
->rules('required', 'max:255'),
Text::make('Email'),
Password::make('Password'),
Text::make('Gender')
->rules('required'),
];
}
转到创建用户表单,它看起来像这样:
当然这不会让它保存它,因为它不知道如何处理gender 字段。为了处理这个问题,我们重写了fillFields 方法。
protected static function fillFields(NovaRequest $request, $model, $fields)
{
// Get all of our user details data
$userDetails = $request->only(['gender']);
// Remove them from the request
$request->request->remove('gender');
$result = parent::fillFields($request, $model, $fields);
// Insert them in the details object after model has been saved.
$result[1][] = function () use ($userDetails, $model){
$model->details()->updateOrCreate(
[],
$userDetails
);
};
return $result;
}
现在我们可以将性别字段视为用户的普通字段,并且不需要UserDetail 资源。要添加更多字段以保存在用户详细信息表中,我们必须将它们添加到我们的唯一并从我们的请求中删除它们。 (将它放在一个数组中会很有意义)
此方法在更新用户时也适用,因为我们选择使用updateOrCreate。
关于这种方法的一个额外说明是我们刚刚引入了一个 n+1 查询,因为我们在尝试获取 gender 属性时延迟加载 details 关系。为了解决这个问题,我们只需覆盖 indexQuery 并将 details 添加到查询构建器。
public static function indexQuery(NovaRequest $request, $query)
{
$query->with('details');
return parent::indexQuery($request, $query);
}