Laravel 5: Model->fill() ignores $fillable property in unit tests
Solution 1
Found the problem: the base seeder in v5.0.x only called Model::unguard() (https://github.com/laravel/laravel/blob/v5.0.22/database/seeds/DatabaseSeeder.php#L15) while v5.1.x was updated and added a call to Model::reguard() (https://github.com/laravel/laravel/blob/v5.1.0/database/seeds/DatabaseSeeder.php#L19) (I was using v5.0.22).
Solution 2
Fillable only applies to MassAssignment. When you're creating a new instance, like what you're doing above, you're not triggering the mass assignment event.
You could do something like this: If you're creating the user anyway, you might as well do:
$user = User::create($request->all);
If you just want to instantiate the user, without persisting the data, you could do something like this:
$user = new User($request);
rvignacio
Updated on June 04, 2022Comments
-
rvignacio about 2 years
I have a user controller with the following validation rules:
public function store(Request $request) { ... $this->validate($request, [ 'name' => 'required', 'email' => 'email|required|unique:users', 'password' => 'confirmed|max:32|min:8|required', 'roles' => 'exists:roles,id|required', ]); $user = new User(); $user->fill($request->all()); ... }
My User.php model defines the fillable properties as:
protected $fillable = ['name', 'email'];
To pass the
confirmed
validation, I have to send bothpassword
andpassword_confirmation
fields in the POST request.During development everything works fine, but in unit tests I'm getting a database error. It tries to insert data into a password_confirmation column. It's like it ignores the
$fillable
array.I know about the "laravel losts event handlers between tests" bug/issue (https://github.com/laravel/framework/issues/1181). So I think that maybe I'm missing to call some model function aside from
Model::boot()
(I'm callingUser::boot()
in the test'ssetUp()
function).Thanks,
Edit
Reading the Model.php source, I've found that someone is calling
Model::unguard()
https://github.com/laravel/framework/blob/5.1/src/Illuminate/Database/Eloquent/Model.php#L2180 after the setUp() function and before the test. If I callUser::reguard()
at the beggining of the test it passes, but (I don't know why), the unguard() and reguard() functions get called multiple times and the test gets really slow. -
rvignacio about 9 yearsCalling
Model::create($attributes)
ends up calling theModel::fill()
function, see Eloquent/Model.php source. The problem is that it respects the $fillable array in dev but not in tests.