I have Vue project with Laravel API, and also I have a column named expired_date: date it is nullable
this is the response after I dd the data from the network console:
The problem is when I store the data I just found the expired_date store value 0000-00-00
My code of store:
$data = $request->except('image');
if (!$request->expired_date) {
$data['expired_date'] = null;
}
Post::create($data);
The issue is that an empty string '' is being saved instead of null, resulting in 0000-00-00 values saved to the field. In this case it's because the ConvertEmptyStringsToNull middleware included with the framework was mistakenly commented out and disabled, so the solution is to re-enable that middleware.
Other common causes are forgetting to make the field nullable in the database, or having an incorrect default value.
To explicitly set a field to null without using the ConvertEmptyStringsToNull middleware, it is possible to use a mutator similar to this inside of the model:
public function setExpiredDateAttribute($date) {
$this->attributes['expired_date'] = empty($date) ? null : Carbon::parse($date);
}
Related
I'm using Laravel 7.
I want to update a JSON column using Laravel's Eloquent. The problem is that if the value of the column is null the column won't be updated.
This is how the code looks like:
Model::update(['jsonColumnName->jsonColumnKey' => 'value']);
This is the SQL that it would generate:
UPDATE model
SET jsonColumnName = JSON_SET(jsonColumnName, '$.jsonColumnKey', 'value');
According to the documentation of JSON_SET, it will take the first parameter as the JSON document that it will modify. In this case, that value would be null since jsonColumnName is currently null. Because of that it returns null since it has nothing to modify and it ends doing nothing.
If I manually set the value of the column to {} and run the showed code, it works. But I guess that you are not expected to do that (right?).
You should make new alter table migration and change json column to have default value {}.
First you need to check if there is already installed dbal with
composer require doctrine/dbal
Then make new migration with code in up() method:
Schema::table('table_name', function (Blueprint $table) {
$table->json('column_name')->nullable()->default(null)->change();
});
Don't forget to backup database before work on it.
With NULL value you can also check if that field is empty.
Another way, on framework level is to set logic about this issue into model's observer.
For example:
public function saving(EntityModel $entityModel)
{
if (is_null($entityModel->json_column)) {
$entityModel->json_column = '{}';
}
}
laravel 5.8
I want a rule of laravel validation for update that be like this:
only push error when the value of this field is null and this field in the database is null too
if the field is null but in the database this field has value that validation is ok
I tried this
'logo' => 'required_without:logo',
You may have to write a custom Rule or do some checks on the field to wrap around your validation definitions.
$rules= [...];
if($model->field === null){
$rules['logo' => 'required'];
}
My laravel version is 5.2. Today I did a test, in my posts table, there are some fields can not be null name title. I save a post like this:
$post = new App\Post();
$post->name = 'testBook';
$post->save();
I found a new record inserted into table, the title field is empty string. So laravel can automatic set not null fields to empty string if I didn't pass values to the attributes?
In my Laravel 5 project, I would like to increase the number of views when a visitor come/refresh on the product page like:
$rds = Product::whereId($id)->first();
$rds->hits++;
$rds->save();
The problem is that the field: updated_at automatically update, which is not what I want at all because I would like to change only field: hits, not update_at field.
If I set $rds->updated_at = false; the field is updated to be '0000-00-00 00:00:0'.
Could you advise how to prevent updated_at field from automatically changing for only certain function?
Best Regards,
Naren
Set the timestamps to false to disable updating created_at and updated_at.
$rds = Product::whereId($id)->first();
$rds->hits++;
$rds->timestamps = false;
$rds->save();
You can have a look at the code by Laravel here in performUpdate method:
\Illuminate\Database\Eloquent\Model.php
// First we need to create a fresh query instance and touch the creation and
// update timestamp on the model which are maintained by us for developer
// convenience. Then we will just continue saving the model instances.
if ($this->timestamps && Arr::get($options, 'timestamps', true)) {
$this->updateTimestamps();
}
it's not $rds->updated_at = false, should be $rds->timestamps = false
Simply put the below in your model it would disable timestamp
public $timestamps = false;
or append to the body of the method, below
$rds->timestamps = false;
NB: The first would disable timestamps permanently, while the other would not allow update of timestamp on your edit.
If I use firstOrCreate then the default values are given for the model that I set up in the database. But when I use firstOrNew the values are not given and are instead given out as NULL. Is there any way to fix this aside from using firstOrCreate?
This is because firstOrNew will just create a new instance of your model when it doesn't get a result from the database. Therefore it does not get the default values from the database.
So I guess you have at least two options here. The first one would be the one you already mentioned using firstOrCreate (this is not something I would recommend because this could lead to incorrect state in your database). Another option would be to add 'Accessorson your model with which will return either the value retrieved from the database or when it'snull` it will return the default value you define.
public function getMyFieldAttribute($myField)
{
if ($myField === null) {
return 'my-default-value';
}
return $myField;
}
More info on accessors can be found in the documentation: https://laravel.com/docs/5.2/eloquent-mutators#accessors-and-mutators