Laravel Model Create in Controller: 4 Ways to Add Extra Field

preview_player
Показать описание
We often need to add additional information to the model being created. And there are various ways to do that, I will show you 4 of them in this video.

- - - - -
Support the channel by checking out my products:

- - - - -
Other places to follow:
Рекомендации по теме
Комментарии
Автор

Alternatively, you can use the "prepareForValidation" method within the request class. It seems links are not allowed in comments, so check out the "Validation" page of Laravel docs and/or the class of Akaunting.

denisdulici
Автор

Happy Teacher's Day, Povilas! 🥳
Thank you for your time, experience and all the knowledge you brought to the Laravel community!
Your work helped thousands of developers. Thank you. ❤

VadimBesedin
Автор

Thanks Povilas for your amazing work as always.

As mentioned by multiple commentors, I personally prefer prepareForValidation() in the form request.

Option 2 and 3 would potentially make slow down tests in addition to the dangers highlighted.

An alternative to option 1 is creating tasks through the relationship in user: i.e Am not saying either is better than the other, just mentioning it here as an alternative.

As regards option 4, I wouldn't advise overriding framework methods if you can avoid it. Especially because prepareForValidation() exists for that purpose but yes its a completely valid option that works.

Samuel.Mwangi
Автор

Another way is to append the user_id to the requested data in the form Request method called prepareForValidation().

renwar
Автор

I would do something like:

$data = $request->validated();
$data['some_key'] = 'some_value';

Model::create($data);

Usually for simple, one-off cases.

thraxxdv
Автор

I always used to push the user_id to the validated inputs array like this:

$validated['user_id'] = auth()->id;


It always make the job done, but in some inner part of me always looking for something more better than my way.... Thank you, dear!

alnahian
Автор

I think this should be done where you set your validation rules. In either the request or the controller. I would keep that logic in the same place.

daihop
Автор

I've made a Blameable Trait for that purpose (which include a boot method which call an Observer) so you don't have to make an Observer for every model. It's still close to your second method.

I indeed had several time run into case where the objects are not created with an user logged, seeders for example. So passing the user_id in the validated FormRequest is a great idea indeed, you can make a generic FormRequest like BlameableFormRequest with the validated method and extends your needed FormRequest with it for example.

aurelienmartel
Автор

I'd recommend _against_ doing it in the observer or the model boot method.
Reason being, you might end up creating that object outside of the auth middleware.
If you have to, at least put that check within an Auth::check call and don't make it override any value set already (observers)

But yeah, you should generally avoid assuming that you're within an auth when you're not in a controller.
If you end up making a console function, or are ever tinkering etc, then you have seriously unexpected behaviour, since those won't have any Auth set.

But ideally, in the form request or controller 👍

Thanks for another great video!

JohnRoux
Автор

The problem with the observe is that when someone else take your code, it is hard to find it.
Personnaly I use it directly on the prepareForValidation Method of the FormRquest Fonction.

nadjinmalade
Автор

Most of the time I create Trait, HasAuthor, and inside that trait I define the relationship and the bootHasAuth method where I'm filling this column.
I'm doing this way because most of the time i need this ability in more then one model

MartinBojmaliev
Автор

I thought for sure this method would come up but it didn't. You can use the FormRequest's prepareForValidation method (not sure if that's spelled correctly) to merge key-value pairs into the request before the validation takes place. It's the perfect moment to add in a value that was not passed in through a form. That way, you can even run the user's id through some additional validation.

intipontt
Автор

All such “magic” can be risky. Service & DTO much cleaner and readable in this case. DI rules))

olehtalanov
Автор

What about
This also adds user-id automatically.

taushifkhatri
Автор

I'm usingh trait for this matter and never been happier

HaiNguyen-cfji
Автор

Hello, this will work (in controller):

$request->merge(['user_id' => auth()->id]);

Szchmausser
Автор

I prefer first method or maybe on validation!!

emuqatash
Автор

If you have defined relation to task in user (you should have) you can do it like that:


or in request class:
public function rules(): array
{
return [
'user_id' => ['required', 'exists:users, id'],
...
];
}

this method add user_id to class request
protected function prepareForValidation(): void
{
$this->merge([
'user_id' => auth()->user()->id,
]);
}

maciejmaciej
Автор

You can assign a new variable with the request validated and attach the user ID to it.

Stoney_Eagle
Автор

I like using ```Task::create([...$request->validated(), 'user_id' => $userId]);```

pizzatime