Laravel Nova:将字段动态绑定到模型上的 JSON 属性

Laravel Nova: Dynamically bind fields to JSON attribute on model

Laravel新星

对于特定项目,我想结合使用 Nova Resource UI 的强大功能和更灵活的数据模型。具体来说,我希望能够将字段添加到存储在 JSON 数据库字段中的属性的资源中,而不是 table.

细节:

数据库模型:引用(包括迁移)

public function up()
{
    Schema::create('quotations', function(Blueprint $table)
    {
        $table->bigInteger('id', true);
        $table->timestamps();
        $table->string('client_name', 100)->nullable();
        $table->string('client_surname', 100)->nullable();
        $table->string('status', 10)->nullable()->default('NEW');
        $table->text('data')->nullable();
    });
}

新星资源

所以我可以定义一个 "normal" NOVA 资源并在 App\Nova\Quotation 中定义以下字段(*忽略状态):

public function fields(Request $request)
{
    return [
        Text::make('Client Name')->sortable(),
        Text::make('Client Surname')->sortable(),


    ];
}

现在我的 "wish" 是为了达到这种效果,使用 不存在的 "bindTo"说明我想要实现的方法

public function fields(Request $request)
{
    return [
        Text::make('Client Name')->sortable(),
        Text::make('Client Surname')->sortable(),

        //Fields bound into the JSON data property  
        Text::make('Client Id')->bindTo('data.client_id),
        Date::make('Client Date Of Birth')->bindTo('data.client_date_of_birth),

        //etc       


    ];
}

因此,当保存 Quotation 模型时,client_name 和 client_surname 属性将正常保存到数据库中。但是 client_id 和 client_date_of_birth 应该保存到 JSON 数据属性。

我知道我可以在 Quotation 模型上设置一个 Mutator

public function setClientIdAttribute($value)
{
      set_data($this->data,'client_id',$value);
}

然而,这仍然需要一个 "non-dynamic" 报价模型。我希望能够动态地将字段添加到视图中,而不必在基础之外更改报价模型。一个真实世界的例子是不同的产品在生成报价之前需要收集不同的输入字段。然后我可以轻松地在 Nova Resource 中动态注入字段定义,同时保持数据库模型简单。

我也尝试了对一个简单问题提出的答案: Laravel Model Dynamic Attribute

但是 - 由于 Nova 仍在寻找 table 上的属性,因此建议的解决方案不起作用。

我很乐意就如何满足此要求获得一些意见。

你可以这样做:

// Model
protected $casts = [
    'data' => 'array'
];

// Nova Resource  
Text::make('Client Id', 'data->client_id')->resolveUsing(function ($value) {
   return $value;
}),