I have a factory with the below definition
public function definition()
{
$startDate = Carbon::createFromFormat('Y', $this->faker->year);
$endDate = $startDate->addYear();
return [
'name' => $startDate->year,
'start_date' => $startDate->format('Y-m-d'),
'end_date' => $endDate->format('Y-m-d'),
];
}
So this generates an array like below
[
'name' => 2020,
'start_date' => '2020-01-30',
'end_date' => '2021-01-30'
]
The above worked as expected until a requirement to return the start_date
field and the end_date
field arose. So in my model I added:
protected $dates = ['created_at', 'updated_at', 'start_date', 'end_date'];
In my validators, I validate that the format is Y-m-d
.
public function rules()
{
return [
'name' => 'required|unique:academic_years',
'start_date' => 'required|date_format:Y-m-d|before_or_equal:end_date',
'end_date' => 'required|date_format:Y-m-d',
];
}
I also have the below test:
public function should_throw_error_if_date_format_is_invalid()
{
Permission::factory()->state(['name' => 'create academic year'])->create();
$user = User::factory()->create();
$user->givePermissionTo('create academic year');
$this->actingAs($user, 'api')->postJson('/api/academic-years', [
'name' => $this->faker->year,
'start_date' => '01-01-2019',
'end_date' => '2019-01-01'
])->assertStatus(422);
$this->actingAs($user, 'api')->postJson('/api/academic-years', [
'name' => $this->faker->year,
'end_date' => '01-01-2019',
'start_date' => '2019-01-01'
])->assertStatus(422);
}
The test fails, but If I remove the $dates
array, the test passes. On checking the object passed into the request I see a different date format {"name":1995,"start_date":"1995-04-04T00:00:00.000000Z","end_date":"1995-04-04T00:00:00.000000Z"}
from the format provided in the Factory
.
How can I resolve this?
Since Faker
is returning a DateTime-Object
which isn't representing a date-string like mysql
likes it (Y-m-d H:i:s
).
You should however be able to access the objects property date
to get the correct string like this:
Try this
public function definition()
{
$startDate = Carbon::createFromFormat('Y', $this->faker->year);
$endDate = $startDate->addYear();
return [
'name' => $startDate->year,
'start_date' => $startDate->format('Y-m-d H:i:s'),
'end_date' => $endDate->format('Y-m-d H:i:s'),
];
}
This should return a date like this string '1995-04-04T00:00:00.000000Z'
or
By default, timestamps are formatted as 'Y-m-d H:i:s'. If you need to customize the timestamp format, set the $dateFormat property on your model. This property determines how date attributes are stored in the database, as well as their format when the model is serialized to an array or JSON:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
/**
* The storage format of the model's date columns.
*
* @var string
*/
protected $dateFormat = 'U';
}