以一种形式从laravel nova中的关系添加字段文本

Lor*_*rti 5 laravel laravel-nova

我是 Laravel Nova 的新手。我正在尝试构建一个用户表单。在这一刻我有这些模型: 用户,用户详细信息

在用户中,我有:电子邮件、密码、用户名。在 UserDetail 我有:姓名、姓氏、性别、号码等。

现在我将为用户创建一个表单。为什么我专注于ONE?因为在我的用户资源字段中,我有:

HasOne::make("UserDetail", "details"),
Run Code Online (Sandbox Code Playgroud)

但是对于设置用户详细信息,我有两种形式:一种用于用户数据(用户名、密码、电子邮件),保存用户后我可以设置详细信息。

所以我不想为 1 个资源编译 2 种不同的形式。

我找到了这个包,但似乎坏了:

https://github.com/yassipad/laravel-nova-nested-form/issues/66

并且字段 UserDetails 未显示。

那么有没有其他方法可以从关系中添加文本字段并在同一个表单中合并?

Oli*_*roe 13

你可以通过使用Laravel 的 accessors 和 mutators来解决这个问题。

在这个例子中,我只会添加genderfromUserDetail因为我很懒。所以我们开始在我们的User模型中添加一个性别访问器

public function details()
{
    return $this->hasOne(UserDetail::class);
}

public function getGenderAttribute()
{
    return $this->details->gender ?? null;
}
Run Code Online (Sandbox Code Playgroud)

此 getter 将从详细信息中获取性别,如果不存在详细信息,则为 null。

现在我们向UserNova 中的资源添加一个新字段。

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'),
    ];
}
Run Code Online (Sandbox Code Playgroud)

转到创建用户表单,它看起来像这样:

在此处输入图片说明

当然这不会让它保存它,因为它不知道如何处理该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;
}
Run Code Online (Sandbox Code Playgroud)

现在我们可以将性别字段视为用户的正常字段,并且不需要UserDetail资源。要添加更多要保存在用户详细信息表中的字段,我们必须将它们添加到我们的 only 并从我们的请求中删除它们。(将它放在数组中是有意义的)

这种方法在更新用户时也有效,因为我们选择使用updateOrCreate. 在此处输入图片说明



关于这种方法的额外说明是我们刚刚引入了一个 n+1 查询,因为我们details在尝试获取gender属性时延迟加载关系。为了解决这个问题,我们只需覆盖indexQuery并添加details到查询构建器。

public static function indexQuery(NovaRequest $request, $query)
{
    $query->with('details');
    return parent::indexQuery($request, $query);
}
Run Code Online (Sandbox Code Playgroud)