How to seed a date field in Laravel 5.3? - php

I've managed to set up a decent amount of seeding for data that needs to be in the database at launch. Everything was easy and working well until I needed to seed a DATE field with a default date.
I've tried the following...
DatabaseSeeder.php
class SettingsTableSeeder extends Seeder {
public function run()
{
Setting::create([
'name' => 'Start Date',
'date' => '2000-01-01'
]);
}
}
In my model I've been told adding this should fix it, but it didn't.
Setting.php
protected $dates = [
'created_at',
'updated_at',
'date'
];
Everytime I go to run the seeder it throws the error:
[InvalidArgumentException]
The separation symbol could not be found
Unexpected data found.
Trailing data
If I remove the quotes around the date it changes to..
[InvalidArgumentException]
The separation symbol could not be found
Data missing
Any idea how one goes about seeding a default value for a DATE database field?

If date is in the $dates array, insert Carbon instance instead of a string:
Setting::create([
'name' => 'Start Date',
'date' => Carbon::parse('2000-01-01')
]);
You'll need to make sure that Carbon is available to use at the top of the file:
use Carbon\Carbon;
It is auto-loaded by Laravel/Composer.

Just try inserting the date using Carbon like,
class SettingsTableSeeder extends Seeder {
public function run(){
Setting::create([
'name' => 'Start Date',
'date' => \Carbon\Carbon::createFromDate(2000,01,01)->toDateTimeString()
]);
}
}

The given answers by Alexey Mezenin and Jaymin Panchal both still resulted in the trailing data error being thrown.
What ended up working for me was including...
use Carbon\Carbon;
at the top of the DatabaseSeeder.php file.
Then changing my Setting::create to...
DB::table('settings')->insert([
'name' => 'Start Date',
'date' => Carbon::create('2000', '01', '01')
]);
for some reason I can't use Carbon with the standard Model::create method while seeding, but it works for DB::table('table')->insert.

$dates= [
['name' =>'Start Date'],
];
foreach ($dates as $date) {
Setting::create($date);
}

Related

Json column - Date field must cast to 'date' in Eloquent model

I have a laravel nova panel like below. Im trying to use a Date field like below:
new Panel('Suggestions', [
Flexible::make('Suggestions')
->addLayout('Suggestions', 'suggestion', [
Text::make('Title'),
Textarea::make('Message'),
Date::make('Date', 'date')
])
->button('Add Suggestion'),
]),
However it shows this error:
{message: "Date field must cast to 'date' in Eloquent model.", exception: "Exception",…}
exception: "Exception"
file: "/var/www/html/vendor/laravel/nova/src/Fields/Date.php"
line: 41
message: "Date field must cast to 'date' in Eloquent model."
I have in the model the casts property like this:
protected $casts = [
'date' => 'date'
];
Do you know what can be the issue?
I don't have a date field on the database table relative to the model. I just have a suggestions json field that has a lot of columns including the "date" column/key, probably that's the issue. Do you know how to solve this issue in this scenario? Thanks
Add this to your casts instead of 'date' => 'date', this solved for me the issue.
protected $casts = [
'flexible-content' => FlexibleCast::class
];
Another options is resolving it and converting it to a MomentJS format which also works fine:
DateTime::make('Date')
->format('DD/MM/YYYY HH:mm')
->resolveUsing(function ($value) {
return $value;
}),
source: https://github.com/whitecube/nova-flexible-content/issues/171
First, I guess you need to rename your db field to something else.
And then
You need to cast your db field into your model like this:
//Casts of the model dates
protected $casts = [
'DB_FIELD_NAME' => 'date'
];

escaping comma for faker on lumen seeder

I'm learning to do some simple migration and seeding on lumen using factory and faker to mysql database, below are my codes :
PostSeeder.php
use Illuminate\Database\Seeder;
class PostSeeder extends Seeder
{
public function run()
{
factory(App\Models\Post::class, 40)->create();
}
}
and on the factory PostFactory.php
$factory->define(Post::class, function (Faker $faker) {
return [
'post_id' => Str::uuid(),
'title' => $faker->sentence(3),
'content' => $faker->realText(200),
'user_id' => Str::uuid(),
'created_at' => $faker->dateTimeBetween('-1 years', 'now')->format('Y-m-d H:i:s'),
'created_by' => Str::uuid(),
'app' => NULL
];
});
when I tried to run the seeder got error like this :
SQLSTATE[22001]: String data, right truncated: 1406 Data too long for
column 'user_id' at row 1 (SQL: insert into 'posts' ('post_id', 'title',
'content', 'user_id', 'created_at', 'created_by', 'app') values
(c1460ae8-e472-4439-aad8-af3aaf090268, Assumenda
ipsa corrupti., King triumphantly, pointing to the shore, and then
treading on her spectacles, and began picking them up again as quickly
as she could. The next thing was snorting like a wild beast,
screamed 'Off.))
I'm not sure, but looks like on faker realText comma is not being escaped on the query, is there anything I need to add on the factory to escape the faker, or need to do something on the database?
I'm using mysql 14.14 on ubuntu 18.04 and lumen 7.x
on posts table the content type is text

Declaration of bedezign\yii2\audit\components\panels\DataStoragePanelTrait::getUrl() using yii2-audit

I am using yii2-audit extension for audit logs, I followed all steps of installation and also migrate all tables.
But when I update table value then it will return error like Audit module cannot be loaded.
I have place behaviors() in my model.
My Model
<?php
namespace frontend\models;
use yii\base\Model;
use yii\web\UploadedFile;
use bedezign\yii2\models\AuditTrail;
use bedezign\yii2\audit\models\AuditEntry;
use bedezign\yii2\Audit;
class StudentForm extends \yii\db\ActiveRecord
{
public function behaviors()
{
return [
'AuditTrailBehavior' => [
'class' => 'bedezign\yii2\audit\AuditTrailBehavior',
// Array with fields to save. You don't need to configure both `allowed` and `ignored`
'allowed' => ['firstname','lastname','email','phone'],
'active' => true,
// Date format to use in stamp - set to "Y-m-d H:i:s" for datetime or "U" for timestamp
'dateFormat' => 'Y-m-d H:i:s',
]
];
}
My question is
Why I am getting error like Audit module cannot be loaded ?
Why any error or other logs are not storing into audit tables ?
I have added audit in main.php
'modules' => [
'audit' => 'bedezign\yii2\audit\Audit',
],
After added I am getting error like below image.

Yii2: Writing to database the date/time of the current record via expression

There is table with some columns. One of it date_of_record. Means the date when current row is inserted in database. In current version i just calculate this field in PHP code before save().
How it should be correctly done via expression? Example by opportunity
Use Timestamp Behaviors In Controller :
use yii\db\Expression;
public function behaviors()
{
return [
[
'class' => TimestampBehavior::className(),
'createdAtAttribute' => 'date_of_record',
'value' => new Expression('NOW()'),
],
];
}
References
1) Timestamp Behaviors
2) Concept Behaviors

Laravel 4: Validate start and end date with before and after validation

I want to validate two date fields in a form which is from_date and end_date. Need to check from_date is less than end_date.
$rules = array('from_date' => array('sometimes','date_format:"Y-m-d"', 'before:'.Input::get('to_date') ),
'to_date' => array('sometimes','date_format:"Y-m-d"', 'after:'.Input::get('from_date') ) );
This is what i tried. But that does not work. If i give the to_date as empty value it will through the error.
I know that it is a question about Laravel 4 BUT if you are using Laravel 5.3 now you can use something like:
$rules = array(
'date_start' => 'required|date_format:Y-m-d|before_or_equal:date_end',
'date_end' => 'required|date_format:Y-m-d|after_or_equal:date_start'
);
$validator = Validator::make($request->all(), $rules);
Please use the below code in laravel 5.2 and it works fine for validating start and end date.
$this->validate($request, [
'start_date' => 'required|before:end_date',
'end_date' => 'required',
]);
Laravel 5:
Here is more extensive approach that follows modern principles and is more Laravel-like. This is a little more complex but still easy to follow and the end results is much cleaner.
Let's start by changing a few things. Let's reduce this to the specific problem, use newer array syntax and apply formatting.
$rules = [
'from_date' => [
'before:'.Input::get('to_date') // This is what we will learn to do
],
'to_date' => [
'after:'.Input::get('from_date') // Do this one on your own
]
];
Now let's create a new Request with php artisan make:request StoreWhateverRequest. This will create the App/HTTP/Request/StoreWhateverRequest.php file. Open that and place your rules in the return array of the rules() function.
return [
'from_date' => 'date',
'to_date' => 'date|after_field:from_date'
];
This will not work yet because after_field isn't available to use yet. Let's create that. We need a new class that extends validator. You can place it in app/Services. We need something similar to:
<?php namespace App\Services;
use Illuminate\Validation\Validator;
use Carbon\Carbon;
class AfterFieldValidator extends Validator {
public function validateAfterField($attribute, $value, $parameters)
{
return Carbon::parse($value) > Carbon::parse($this->data[$parameters[0]]);
}
}
In the above we have: $attribute which is the name of the field we are checking (to_date), $value is the value of the field we are checking and $parameters is the parameters we passed to the Validator(from_date) seen in 'to_date' => 'date|afterField:from_date'. We also need the other data fields passed to the Validator, we can get these with $this->data. Then we just have to preform the logic appropriately. You really don't even need Carbon here but be sure to parse the string so we don't do string comparison.
Now we need to load this into the application. To do this put the below code inside the boot() function in app/Providers/AppServiceProviders.php.
Validator::resolver(function($translator, $data, $rules, $messages)
{
return new afterFieldValidator($translator, $data, $rules, $messages);
});
The final step is easiest. Just inject and instance of StoreWhateverRequest into our Controller.
...
public function store(StoreWhateverRequest $request)
{
...
All done. I feel this is a pretty SOLID way to solve the problem.
Just came across this and thought I'd share an answer I found: Compare attributes in validation
Basically, you'd create a new Validator that extends Illuminate\Validation\Validator and write a custom rule in there:
public function validateEndAfter($attribute, $value, $parameters) {
$start_date = $this->getValue($parameters[0]); // get the value of the parameter (start_date)
return (strtotime($value) > strtotime($start_date));
}
then in your validator use the new rule:
$rules = [
'start_date' => 'required',
'end_date'=> 'required|end_after:start_date',
]
Anyhow,
I did as like this. So that even if any date in the form is empty that will auto fill and check the validation
$inputs = Input::all();
if(!empty($inputs))
{
$default_date_arr = array('from_date' => date('Y-m-d', strtotime('-1 days')), 'to_date' => date('Y-m-d'));
$inputs = $inputs+$default_date_arr;
}
$rules = array('from_date' => array('sometimes','date_format:"Y-m-d"', 'before:'.$to_date) ,
'to_date' => array('sometimes','date_format:"Y-m-d"', 'after:'.$from_date ) );
$validator = Validator::make($inputs,$rules);
if($validator->fails())
{ ... }
This may not be the answer for what i asked. But i needed just a way to finish this. May be will helpful for others.

Categories