Pass empty fields on the update method using Larav

2019-06-09 08:46发布

问题:

I'm getting data through a classic submitted form but for some reason I don't get all the input's data in request and it only updates the received ones.

Model::find($id)->update($request->all());

This is a bit problematic because I have multiple nullable fields in my database and sometimes I want to pass empty fields (i.e when a user clear an input then submit the form)

Do you know a way to pass empty fields to the Request as well?

回答1:

The thing is, Laravel transforms the '' values to null by default through the ConvertEmptyStringsToNull middleware. Check your Kernel:

app/Http/Kernel.php

protected $middleware = [
    // ...
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    // ...
];

This middleware do the following:

protected function transform($key, $value)
{
    return is_string($value) && $value === '' ? null : $value;
}

As you can see, if the given attribute has a value '' it will be transformed to null.

So, to avoid this you could just comment that middleware in the Kernel file. But be aware of this, because this will be applied to your entire application.



回答2:

Input Trimming & Normalization
Laravel version > 5.4 already has these features included:


For versions < 5.4: make a new middleware with following code:

public function handle($request, Closure $next)
{
    foreach ($request->input() as $key => $value) {
        if (! $value) {
            $request->request->set($key, NULL);
        }
    }

    return $next($request);
}

and assign it to the routes or controller's methods you want it to take place:

Route::post('/route/{id}', [
   'middleware' => NewMiddleware::class,
], function (Request $request, $id) {
    Model::find($id)->update($request->all());
});

REMEMBER: create(), update(), etc. methods work on fields in $fillable array in your model:

class User extends Model
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name', 'email', 'contact', ];
}

Or if you want to exclude some fields and include rest, use $guarded array instead:

class User extends Model
{
    /**
     * The attributes that aren't mass assignable.
     *
     * @var array
     */
    protected $guarded = ['details'];
}

If your field is not in the $fillable array in "Model" class, the update() method will not work for that field!!!

Reference: Mass Assignment



回答3:

You can use php array_merge() like with this code as i use that

$contentCategory->update(array_merge($request->all(), ["FIELD1" => '',"FIELD2" => '']));

or test this code:

$request->request->add(['FIELD1' => '','FIELD2' => '']);


回答4:

Somehow I managed to make it work: on my web application I have disabled ConvertEmptyStringsToNull middleware (commented it) so when I log the $request I get empty values '' and on the API, $request logs null value for each field.