0
votes

Laravel Nova

For a particular project, I would like to use the power of the Nova Resource UI combined with a more flexable data model. Specifically, I want to be able to add fields to the resource for attributes stored inside a JSON database field, and not on the table.

Specifics:

Database model: quotations (migration included)

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();
    });
}

Nova Resource

So I can define a "normal" NOVA resource and define the following fields (*ignoring status) in App\Nova\Quotation:

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


    ];
}

Now my "wish" is to have something to this effect, using the non-existant "bindTo" method to illustrate what I want to achieve

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       


    ];
}

So when a Quotation model is saved, the client_name and client_surname attributes will save to the database as per normal. but client_id and client_date_of_birth should save to the JSON data attribute.

I know I can set up a Mutator on the Quotation model

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

However that would still require a "non-dynamic" Quoation model. I want to be able to add fields to the view dynmiacally without having to change the Quotation model beyond the basics. A real world example would be where different products have different input fields to gather before generating a quote. I could then easily inject the field deffinition dynamically in the Nova Resource whilst keeping the database model simple.

I also tried the answer proposed to a simpliar question: Laravel Model Dynamic Attribute

However - the sollution proposed does not work since Nova is still looking for the attribues on the table.

I would love to get some input on how to tackle this requirement.

1

1 Answers

3
votes

you can do something like this:

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

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