harryg
harryg

Reputation: 24077

Laravel Model Factories and Eloquent; setting dates

So I have an App\Post model in my app, defined as follows:

namespace App;
class Post extends Model 
{

    use SoftDeletes;

    protected $dates = ['created_at', 'updated_at', 'published_at', 'deleted_at'];
    // etc...
}

I created a model factory, a nice new feature as of Laravel 5.1 to define the blueprint of a Post as follows:

$factory->define('App\Post', function($faker) {
    return [
    'title'     => $faker->sentence,
    'content'   => $faker->paragraph,
    'published_at' => $faker->dateTimeThisMonth(),
    ];
});

As we can see I set the published_at field to be a random date this month, as generated by the Faker instance. The method used returns an instance of DateTime.

However when I generate some Posts I find the published_at field to be null, suggesting that the DateTime instance is not being correctly interpreted.

I found that if I changed that line to:

'published_at' => Carbon::instance($faker->dateTimeThisMonth())->toDateTimeString(),

which essentially converts the DateTime to a Carbon and then outputs a date-time string e.g. "2015-06-15 13:44:23", it works correctly.

Is this really the best way to define faker dates in model factories? I would've thought the fact that I defined published_at in the $dates array Laravel would interpret the DateTime (or Carbon) instance and save it without me having to provide a string.

Edit

I'm finding that this is also not working for simple Eloquent creates:

E.g. if I run

App\Post::create([
    'title' => $title,
    'content' => $faker->paragraph(4),      
    'published_at' => new Carbon,
    'created_at' => Carbon::parse('2015-06-16')
]);

The published_at and created_at field are still null. Any ideas?

Upvotes: 7

Views: 12178

Answers (2)

chanafdo
chanafdo

Reputation: 5124

You can use Carbon dates inside model factories without a problem.

In order to make it work please add the published_at and created_at to the $fillable property.

Then it should work fine.

Upvotes: 0

Tim
Tim

Reputation: 5943

Since Faker is returning a DateTime-Object which isn't representing a date-string like mysql likes it (Y-m-d H:i:s) the field will be set to null.

You should however be able to access the objects property date to get the correct string like this:

$faker->dateTimeThisMonth()->format('Y-m-d H:i:s')

This should return a date like this string '2015-06-19 13:07:07' (length=19)

Upvotes: 7

Related Questions