Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

CookieMonster's avatar

When to use $request->all()?

After submitting a form, there are two ways to retrieve the input from the controller:

Using $request->all():

user()->todos()->create($request->all());

Specifying each field:

$todos = new Todos;

$todos->title = $request->input('field_1');

$todos->description = $request->input('field_2)';

......

$todos->save();

The first way obviously only requires to write one line of code but is there any pros or cons or using either way?

0 likes
28 replies
aletopo's avatar

@nickywan123 i think there are no cons in using that method. Because only the properties that the model defines in $fillable can be written en masse.

CookieMonster's avatar

No cons in using which method?

I get that the second method requires more line of code written but for the first method, we won't know what input fields are coming from the HTTP request unless we do a dd().

Wouldn't the second method also checks the $fillable property to make sure there's mass assignment?

trin's avatar

no, $fillable checks only on create method. if you fear, use like

user()->todos()->create($request->only([
	'title',
	'description',
	'user_id'
]))
CookieMonster's avatar

In your way, the database column name has to match with the attributes, like 'user_id' should be of same name as 'user_id' in the db right?

So if I use request input and save it manually, then what happens when the column field does not exist in the table?

If I remember, it will throw the mass assignment error too.

aletopo's avatar

No cons using $request->all()

Mass assignement is only when use an array. Assigning once property at time is not "mass" assignment. That is why @trin says.

dd() is only for debugging, in production is not used.

Sorry, i dont speak english so you i cannot understand the real sense of you reply.

CookieMonster's avatar

Okay. Because I remember when I assign the input one by one and I did not put a column in my $protected model and it still shows mass assignment error. If that makes sense.

trin's avatar

you understood correctly, the column names must match the passed parameters from the request and when you use $request->all() or $request->only(['title', 'description', 'user_id']) if you have different parameter names, you can use

$todo = new Todos;
$todo->title = $request->input('name');
...

or

$todo = Todos::create([
	'title' => $request->input('name')
])

usualy i use construction like

$todo = Todos::create(array_merge(
	$request->only(['title', 'description']),
	[
		'user_id' => $request->input('user')
	]
))

but no problem to use $request->all(), if your db columns name match request parameters name

1 like
CookieMonster's avatar

Okay I understood now, if I use:

$todo = new Todos;
$todo->title = $request->input('description');
...

and description exist in the database column but not in $protected = ['address'], will it still throw any sort of error?

trin's avatar

🤦‍♂️ sorry 4 my english. no, you not understood. method create can simplify code to create new model.

$todo = new Todos;
$todo->title = 123;
$todo->description = 456;
$todo->save();

can simplified to

$todo = Todos::create(['title' => 123, 'description' => 456]);

but only if title and description exists in $fillable array of model. if in $filleable you have only title, for example, you anyway create new $todo with create method, but description will not be setted. code run with zero error.

when you use $resquest->all(), you get an array with all http parameters (get/post/etc).

in your example

$todo = new Todos;
$todo->title = $request->input('description');

you create new Todos model and set title to $_REQUEST['description']

CookieMonster's avatar

Okay but you mentioned this

if in $filleable you have only title, for example, you anyway create new $todo with create method, but description will not be setted. code run with zero error.

I think you mean you have $fillable = ['tite', 'description']

and then you create todo with create method like

$todo = Todos::create(['title' => 123]);

then it will no show error. Is that what you mean?

trin's avatar

i mean if you have

protected $fillable = ['title'];

and you create model by

$todo = Todos::create(['title' => 123, 'description' => 456]);

your model will be created, but description will not be setted, because desciption not in $fillable

if

protected $fillable = ['tite', 'description'];

and

$todo = Todos::create(['title' => 123]);

model will be created too and description will be setted to null. if it possible in your db.

trin's avatar

in both, if description cant be null.and in none, if can

CookieMonster's avatar

I usually do this:

$todo = new Todos;
$todo->title = 123;
$todo->description = 456;
$todo->save();

It will give an error if description is not a column in db or another field with description_2 which is not nullable.

Snapey's avatar

there is no good EXCUSE for using $request->all()

it's just lazy

CookieMonster's avatar

So the best way is to use $request->only([....]) or manual insertion to the db?

PaulMaxOS's avatar

Just out of interest - who’s saying that $request->all() is a good refactor?

Honestly, I can’t think of a situation where I would do this or where I’d approve a PR where this is being done.

To me it looks like people are suggesting this to be a proper refactor because they think that less code is always better or so...

Tray2's avatar

A request should always be validated before you use any of the data on your application. That goes even if you use $fillable in your model.

No matter if you use inline validation (validation in your controller) or a form request class, after validation never use request->all()

This is a bad practice in my book

$request->validate(['title' => 'required', 'body' => 'required' ]);
Post::create($request->all());

It's much better to just

Post::create($request->validate(['title' => 'required', 'body' => 'required' ]));

Or even better use a form request class for it

public function store(PostFormRequest $request)
{
  Post::create($request->validated);
}
2 likes
CookieMonster's avatar

What about this?

$request->validate(['title' => 'required', 'body' => 'required' ]);

$post = new Post

$post->title = $request->input('title');

$post->body = $request->input('body');

$post->save();

or

$request->validate(['title' => 'required', 'body' => 'required' ]);

Post::create($request->only(['title','body']));

newbie360's avatar

for me, if i see any of this code, if means not validated and i don't trust the value

$request->only(['title','body'])

but if i see this, it mean i trust the value

$request->validated()
$request->validated()['title']
$request->validated()['body']
Tray2's avatar

This

$request->validate(['title' => 'required', 'body' => 'required' ]);

$post = new Post

$post->title = $request->input('title');

$post->body = $request->input('body');

$post->save();

Should in that case be

$postData = $request->validate(['title' => 'required', 'body' => 'required' ]);

$post = new Post();

$post->title = $postData['title'];

$post->body = $postData['body'];

$post->save();

And

$request->validate(['title' => 'required', 'body' => 'required' ]);

Post::create($request->only(['title','body']));

Should be

Post::create($request->validate(['title' => 'required', 'body' => 'required' ]));

However you do as you please and I'll go with this every day of the week.

public function store(PostFormRequest $request)
{
  Post::create($request->validated);
}
CookieMonster's avatar
$request->validate(['title' => 'required', 'body' => 'required' ]);

$post = new Post

$post->title = $request->input('title');

$post->body = $request->input('body');

$post->save();

For the above, wouldn't it return to previous page if it doesn't pass the validate in 1st line of code?

For this :

public function store(PostFormRequest $request)
{
  Post::create($request->validated);
}

For each form, we create a new request form?

Snapey's avatar

For the above, wouldn't it return to previous page if it doesn't pass the validate in 1st line of code?

Throws a validation exception which is caught automatically and returned back with input.

For each form, we create a new request form?

Yes

DjInfusion's avatar

I always set the model to $guarded = [];

That's crazy talk you say. Not really.

If you validate everything in the controller, like this:

$attributes = $request->validate([
    'field_1' => 'required|min:3',
    'field_2' => 'required',
    // etc etc....
]);

Then you can drop it into your database like so:

Model::create($attributes);

No need to mass assignemnt protection, as you've validated everything in the controller first.

Snapey's avatar

@djinfusion thats no different to this;

Post::create($request->validate(['title' => 'required', 'body' => 'required' ]));

except that you used a temporary variable.

1 like
DjInfusion's avatar

That's pretty damn cool. I'll be using that from now on.

Please or to participate in this conversation.