9

I am developing a web admin panel using Laravel Nova.

I am having an issue since Nova is quite a new technology.

What I would like to do now is I would like to add a hidden field or extend or override the create method.

This is my scenario. Let's say I have a vacancy nova resource with the following field.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        Text::make('Title')->sortable(),
        Text::make('Salary')->sortable()
        // I will have another field, called created_by
    ];
}

Very simple. What I like to do is I want to add a new field called created_by into the database. Then that field will be auto filled with the current logged user id ($request->user()->id).

How can I override or extend the create function of Nova? How can I achieve it?

I can use resource event, but how can I retrieve the logged in user in the event?

Darmen Amanbay
  • 4,869
  • 3
  • 29
  • 50
Wai Yan Hein
  • 13,651
  • 35
  • 180
  • 372

5 Answers5

20

What you're looking for is Resource Events.

From the docs:

All Nova operations use the typical save, delete, forceDelete, restore Eloquent methods you are familiar with. Therefore, it is easy to listen for model events triggered by Nova and react to them. The easiest approach is to simply attach a model observer to a model:

If you don't feel like creating a new observable you could also create a boot method in your eloquent model as so:

public static function boot()
{
    parent::boot();

    static::creating(function ($vacancy) {
        $vacancy->created_by = auth()->user()->id;
    });
}

But please do note that these are a bit harder to track than observables, and you or a next developer in the future might be scratching their head, wondering how's the "created_at" property set.

Elena Kolevska
  • 617
  • 5
  • 10
  • I personally find this approach easier to "find" than inside an observable, since the very first thing I do when I want to know about a model behavior is to go to the model definition. Either ways are fine, clean, and acceptable, in my opinion... – Internetbug256 Dec 03 '21 at 20:09
12

In my opinion you should go for Observers. Observers will make you code more readable and trackable.

Here is how you can achieve the same with Laravel Observers.

AppServiceProvider.php

public function boot()
{
    Nova::serving(function () {
        Post::observe(PostObserver::class);
    });
}

PostObserver.php

public function creating(Post $post)
{
    $post->created_by = Auth::user()->id;   
}

OR

You can simply hack a Nova field using withMeta.

Text::make('created_by')->withMeta([
    'type' => 'hidden',
    'value' => Auth::user()->id
])
J Foley
  • 1,038
  • 1
  • 17
  • 30
Fawzan
  • 4,738
  • 8
  • 41
  • 85
4

You could also do that directly within your Nova resource. Every Nova resource has newModel() method which is called when resource loads fresh instance of your model from db. You can override it and put there your logic for setting any default values (you should always check if values already exist, and only set if they are null, which will only be the case when the model is being created for the first time, which is what you actually need):

public static function newModel()
{
    $model = static::$model;
    $instance = new $model;

    if ($instance->created_by == null) {
        $instance->created_by = auth()->user()->id;
    }

    return $instance;
}
ElectroBuddha
  • 630
  • 10
  • 20
1

Since Nova v3.0, there is a native Hidden field.

Usage:

Hidden::make('Created By', 'created_by')
    ->default(
        function ($request) {
            return $request->user()->id;
        }),

Docs: https://nova.laravel.com/docs/3.0/resources/fields.html#hidden-field

scadh
  • 75
  • 6
  • This doesn't work for everyone because you may information that is part of the 'saving' event – kemp Apr 09 '21 at 14:34
0

a) Create an Observer class with following command:

php artisan make:observer -m "Post" PostObserver

b) Add following code in the PostObserver:

$post->created_by = Auth::user()->id;

c) Register PostObserver in AppServiceProvider.php

For detailed explanation: https://medium.com/vineeth-vijayan/how-to-add-a-new-field-in-laravel-nova-resource-87f79427d38c

Vineeth Vijayan
  • 1,215
  • 1
  • 21
  • 33