0

I have been trying to get seeding set up with the first table on my site using the model factory. The seeds that I entered manually work, but I wanted to make sure I could seed using the factory, as well, for future tests and all that jazz. The manual entries work just fine, but creating using the model factory results in an SQL statement that is only updating the timestamps. It inserts a blank row (except for the timestamps), then fails because of a unique constraint on one of the columns, so it can't enter another blank row. I've not been able to figure out why it's not generating the correct inserts, even though the factory is actually creating a good set of data. (As tested by printing out the array.) Any help on how to troubleshoot this would be most welcome.

Model Factory:

$factory->define(App\Models\Site::class, function (Faker\Generator $faker) {
    $site = new App\Models\Site;
    $siteTypes = array_keys($site->siteTypes);
    $return = [
        'site_name' => $faker->word
        , 'site_url' => $faker->url
        , 'site_type' => $faker->randomElement($siteTypes)
        , 'is_active' => round(rand(0,1))
        , 'created_at' => $faker->unixTime
        , 'updated_at' => $faker->unixTime
    ];
    return $return;
});

DatabaseSeeder.php:

use Illuminate\Database\Seeder;
use Illuminate\Database\Eloquent\Model;
use App\Models\Site;

class DatabaseSeeder extends Seeder
{
    public function run() {
        Model::unguard();
        DB::delete('delete from sites');
        DB::statement('alter table sites auto_increment = 1');
        $this->call(SiteTableSeeder::class);
        DB::statement('alter table sites auto_increment = 10000');
        Model::reguard();
    }
}

SiteTableSeeder:

class SiteTableSeeder extends Seeder
{
    public function run()
    {
        <snip out the other manual seeds>
        DB::table('sites')->insert([
            'site_id' => 9999,
            'site_name' => 'Generic Online Site',
            'site_url' => 'http://generic.nextworth.com',
            'site_type' => 'online',
            'is_active' => 1,
        ]);
        factory('App\Models\Site', 5)->create();
    }
}
llhilton
  • 170
  • 5
  • 15

2 Answers2

1

https://stackoverflow.com/a/33716768/2666477 actually had the answer. I am using the __construct method, but I wasn't doing the attributes thing. I added that, and all is well. Thank goodness! :)

Community
  • 1
  • 1
llhilton
  • 170
  • 5
  • 15
0

created_at and updated_at doesn't use unix time. Use $faker->dateTime($max = 'now');

Laravel will automatically update these values when the models are being modified, so probably what's happening is that the seeding fails but it had already created the record and added the updated_at and created_at values

Pistachio
  • 1,652
  • 1
  • 18
  • 38
  • Didn't mention it, but I'm using unix timestamps. I've set that in the model, and the SQL insert statement has the timestamps in the right format, so I'm not worried about that. I just have no idea why the rest of the data isn't making it into the database. If it's true to form on most of my errors, it's something simple I'm overlooking. :) ETA: I've tried it with and without the faker timestamps and get the same result. – llhilton Nov 24 '15 at 03:14
  • Are you doing `$this->call(SiteTableSeeder::class);` in your `DatabaseSeeder.php`? – Pistachio Nov 24 '15 at 03:28
  • Yep, exactly like that. I'll edit my post to add the full database seeder file and split out the sitetableseeder file. – llhilton Nov 24 '15 at 14:12
  • I've been poking through the Laravel code, and it seems like this is something that's going haywire in the factory somewhere, but I can't figure out where. And I feel sure I've forgotten something very basic somewhere, like a Use statement or something, but my comparisons to things that work haven't yielded anything yet. Perplexing. And for more fun, I tried seeding a different table instead using its model, but I'm getting the same thing. – llhilton Nov 24 '15 at 15:24