I'm trying to create entities using mass-assignment Eloquent feature...
$new = new Contact(Input::all()); $new->save();
The problem's that this way, every field's filled out with an empty string instead of null
values as I expected.
I'm currently developing the system and still some table columns're not defined, that's why using this method, to avoid adding every new field to $fillable
array and to a new Contact(array(...));
...
Also I've around 20 fields in this table, so It'd be a bit ugly to have an array such as
$new = new Contact(array( 'salutation' => Input::get('salutation'), 'first_name' => Input::get('first_name'), 'last_name' => Input::get('last_name'), 'company_id' => Input::get('company_id'), 'city' => ... ... ));
Any tips of how to do this or fix?
Update By now I've sorted out this doing the array_filter in the App::before()
filter.
Update In filter was a bit mess. I end up doing:
public static function allEmptyIdsToNull() { $input = Input::all(); $result = preg_grep_keys ( '/_id$/' , $input ); $nulledResults = array_map(function($item) { if (empty($item)) return null; return $item; }, $result); return array_merge($input, $nulledResults); }
And in my functions.php.
if ( ! function_exists('preg_grep_keys')) { /** * This function gets does the same as preg_grep but applies the regex * to the array keys instead to the array values as this last does. * Returns an array containing only the keys that match the exp. * * @author Daniel Klein * * @param string $pattern * @param array $input * @param integer $flags * @return array */ function preg_grep_keys($pattern, array $input, $flags = 0) { return array_intersect_key($input, array_flip(preg_grep($pattern, array_keys($input), $flags))); } }
By now only working with fields that ends with "_id". This is my biggest problem as if a relationship is not NULL
, the database will throw an error as the foreign key "" cannot be found.
Works perfect. Any comment?
However, it will throw an error of unique constraint if you use an empty string here. So, NULL is better. An empty string is useful when the data comes from multiple resources. NULL is used when some fields are optional, and the data is unknown.
An empty string is a string instance of zero length, whereas a null string has no value at all. An empty string is represented as "" . It is a character sequence of zero characters. A null string is represented by null .
Check if not null: whereNotNullSELECT * FROM users WHERE last_name IS NOT NULL; The equivalent to the IS NOT NULL condition in Laravel Eloquent is the whereNotNull method, which allows you to verify if a specific column's value is not NULL .
Method #1 : Using lambda In this we check for string for None or empty string using the or operator and replace the empty string with None.
I've looked for the answer to this myself, and the closest I can come up with is using Mutators (http://laravel.com/docs/eloquent#accessors-and-mutators).
The same problem was solved by adding a (magic!) Mutator method for the foreign key field in the model:
public function setHeaderImageIdAttribute($value) { $this->attributes['header_image_id'] = $value ?: null; }
For a table with a lot of foreign keys, this can get kind of bulky, but it's the most "built-in" method I've found for handling this. The upside is that it's magic, so all you have to do is create the method and you're good to go.
UPDATE -- Laravel 5.4 and above
As of Laravel 5.4, the \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class
middleware handles this when the request is received. In my example above, if the request contains an empty string value for 'header_image_id', this middleware automatically converts it to null
before I can assign it to my model.
If it is necessary you could remove any empty string in an array by filtering.
$input = array_filter(Input::all(), 'strlen');
Then if you have something like array('a' => 'a', 'b' => '')
you will get: array('a' => 'a')
.
As far as I know, if a field is not specified in the array for mass-assignment, then Laravel Eloquent ORM will treat it like NULL
.
$input = array_filter(Request::all(), 'strlen');
or
// If you inject the request. $input = array_filter($request->all(), 'strlen');
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With