laravel模型工厂种子从现有产生

时间:2016-03-17 04:22:35

标签: laravel-5 factory laravel-seeding

我正在尝试使用外键播种一个表,但我仍然不知道如何告诉模型从已存在的内容中随机提取值。

ModelFactory

var wallpaper = data.wallpapers[Math.floor(Math.random() * data.wallpapers.length)];
...
url:wallpaper.url_image,
...

种子

VendorTableSeeder

$factory->define(App\Vendor::class, function(Faker\Generator $faker) {
    return [
        'name' => $faker->company,
    ];
});

$factory->define(App\Device::class, function(Faker\Generator $faker) {
    return [
        'vendor' => ,
        'name' => $faker->company,
        'mac_address' => $faker->macAddress,
    ];
});

DeviceTableSeeder

public function run()
{
    factory(App\Vendor::class, 150)->create();
}

DataSeeder

public function run()
{
    factory(App\Device::class, 50)->create();
}

我在Device表之前种植Vendor表,并希望从现有供应商中填充随机供应商ID。

$this->call(VendorTableSeeder::class);
$this->call(DeviceTableSeeder::class);

但我得到了

'vendor' => 'factory::App\Vendor'

看起来插件试图将SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: foreign key constraint fails 作为供应商列的字符串插入。我试图找出如何从现有供应商那里获取它。

3 个答案:

答案 0 :(得分:4)

VendorTableSeeder开始同时播种它们。

您是否需要没有供应商的设备?或没有设备的供应商?如果没有,那么这是最好的选择。相关表格应该一起播种。

更好的例子是学校。学校是主要的种子,每个学校,你也会有一个校长,几个教师和100个学生。如果你一次播种它们就可以消除对外键或订购的担忧。

factory(App\Vendor::class, 150)
    ->create()
    ->each(function (App\Vendor $vendor) {
        $vendor->devices()->save(
            factory(App\Device::class)->make()
        );

        // For some randomness
        $vendor->devices()->save(
            factory(App\Device::class, rand(0, 4))->make()
        );
    });

如果您确实希望单独播种它们的灵活性,那么您还有其他几种选择。您可以在设备工厂内部拉入随机供应商。

$factory->define(App\Device::class, function(Faker\Generator $faker) {

    // Grab a random vendor
    $vendor = App\Vendor::orderByRaw('RAND()')->first();

    // Or create a new vendor
    $vendor = factory(App\Vendor::class)->create();

    return [
        'vendor_id'   => $vendor->id,
        'name'        => $faker->company,
        'mac_address' => $faker->macAddress,
    ];
});

或者您可以传递与工厂生成的属性合并的额外属性。

// $vendor is a Vendor object

factory(App\Device::class, 50)->create([
    'vendor_id' => $vendor->id,
]);

答案 1 :(得分:0)

以下是我使用我的地址的方式,我在10%的时间内创建新地址,否则使用随机地址。

// Grab a random address
$address = App\Address::orderByRaw('RAND()')->first();

// 10% that we will generate a new address
if ($faker->boolean(10) || !$address)
{
    $address = factory(App\Address::class)->create();
}

基本上我抓了一个随机地址,如果它存在,$faker->boolean(10)将返回true的概率为10%,它将生成一个新地址。但是,如果没有地址($address == false),我们总是会生成一个新地址。

答案 2 :(得分:0)

这是使用random()方法生成发电机工厂的简单方法

$factory->define(App\Device::class, function(Faker\Generator $faker) {
    return [
        // another way to, Get any random row from existing records
        'vendor_id' => App\Vendor::all()->random()->user_id,
        'name'        => $faker->company,
        'mac_address' => $faker->macAddress,
    ];
});