0

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 Answer 1

5

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;
}),
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you! That actually does exactly what I was after, but it looks like I was only missing the way to identify the field name via the data property - so adding the data->custom_field_name is actually all I needed. Resolveusing or DisplayUsing is not nececary and probably more applicable if I want to change the actual value.
You are welcome! :) Yes, Resolveusing or DisplayUsing are optional.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.