【问题标题】:laravel model factory seed generate from existinglaravel 模型工厂种子从现有生成
【发布时间】:2016-07-03 06:35:21
【问题描述】:

我正在尝试使用外键为表播种,但我不知道如何告诉模型从已经存在的数据中随机提取值。

模型工厂

$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,
    ];
});

种子

VendorTableSeeder

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

DeviceTableSeeder

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

DataSeeder

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

我在设备表之前播种供应商表,并希望从现有供应商中填充随机供应商 ID。

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

但我得到了

SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: foreign key constraint fails

看起来插入试图插入factory::App\Vendor 作为供应商列的字符串。我正在尝试弄清楚如何从现有供应商那里获得它。

【问题讨论】:

    标签: laravel-5 factory laravel-seeding


    【解决方案1】:

    这是使用 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,
        ];
    });
    

    【讨论】:

      【解决方案2】:

      这是我使用地址的方法,我做到了 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) 有 10% 的机会返回 true 并生成一个新地址。但是,如果没有地址 ($address == false),我们总是会生成一个新地址。

      【讨论】:

        【解决方案3】:

        同时从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,
        ]);
        

        【讨论】:

          猜你喜欢
          • 2016-10-17
          • 1970-01-01
          • 2017-10-21
          • 2018-08-11
          • 1970-01-01
          • 1970-01-01
          • 2021-09-29
          • 2018-04-21
          • 2018-06-09
          相关资源
          最近更新 更多