I am working on a multi-step registration form. In the first step, I need to collect first_name
, last_name
, and dob
, then create a Customer
object with only those three fields:
// RegistrationController.php
public function store_profile(Request $request) {
$rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
$this->validate($request, $rules);
Customer::create($request);
}
The problem is that other fields, such as address
, city
, state
, etc. are also fillable:
// Customer.php
protected $fillable = ['first_name', 'last_name', 'dob', 'address', 'city', 'state', ...];
I intend to collect them in the second step of the registration (in public function store_address()
), yet nothing will prevent the user from POST
ing those additional fields to step one:
// RegistrationController.php
public function store_profile(Request $request) {
$rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
$this->validate($request, $rules); // won't validate 'address', 'city', 'state'
Customer::create($request); // will store everything that's fillable,
// no matter if it was validated or not...
}
Hence, my goal is to filter $request->all()
fields by the array keys defined in my validation $rules
variable. Here's my attempt:
$data = [];
foreach(array_keys($rules) as $key) {
$val = $request->{$key};
if (! empty($val))
$data[$key] = $val;
}
// in the end, $data will only contain the keys from $rules
// i.e. 'first_name', 'last_name', 'dob'
First, is there a more efficient/concise way to do it using array_column
or array_intersect_key
or other, possibly without manual looping? Second, is there a more Laravel-like approach that I am not aware of?
What about only()
(and except()
)?
Customer::create($request->only(['first_name', 'last_name', 'dob']));
or
Customer::create($request->only(array_keys($rules)));
Edit: In Laravel 5.5, there's another solution:
$rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
$data = $this->validate($request, $rules);
Customer::create($data); // $data contains only first_name, last_name and dob
I would have done like this if I were you:
public function store_profile(Request $request) {
$rules = ['first_name' => '...', 'last_name' => '...', 'dob' => '...'];
$this->validate($request, $rules); // won't validate 'address', 'city', 'state'
Customer::create([
'first_name' => $request->input('first_name');
'last_name' => $request->input('last_name');
'dob' => $request->input('dob');
]);
}
or even simpler:
Customer::create($request->only(['first_name', 'last_name', 'dob']));