3

外部キーを使用してテーブルをシードしようとしていますが、既存のものからランダムに値を取得するようにモデルに指示する方法に行き詰まっています。

モデルファクトリー

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

ベンダーテーブルシーダー

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

DeviceTableSeeder

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

データシーダー

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

Device テーブルの前に Vendor テーブルをシードし、既存のベンダーからランダムなベンダー 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挿入がベンダー列の文字列として挿入しようとしているようです。既存のベンダーから引き抜く方法を見つけようとしています。

4

3 に答える 3

4

から同時にシードしますVendorTableSeeder

ベンダーのいないデバイスが必要になることはありますか? または、デバイスを持たないベンダーですか? そうでない場合は、これが最適なオプションです。関連するテーブルは一緒にシードする必要があります。

より良い例は、学校です。School がメインのシードであり、各 School に対して、校長、数人の教師、および 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-03-17T21:12:46.610 に答える
1

これが私が自分のアドレスでそれを行った方法です.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();
}

基本的にランダムなアドレスを取得します。存在する場合、10% の確率でアドレス$faker->boolean(10)が返さtrueれ、新しいアドレスが生成されます。ただし、アドレス ( ) がない場合は、$address == false常に新しいアドレスを生成します。

于 2016-08-06T14:29:13.617 に答える