【问题标题】:Laravel (5.6) how to seed tables with relationships to other tablesLaravel(5.6)如何为与其他表有关系的表播种
【发布时间】:2018-08-19 12:42:37
【问题描述】:

目前有一些停机时间,我想玩一下 laravel,因为我通常只将它用于基本的 Web 开发。

我尝试过播种器,并且喜欢将测试数据放入表中的速度更快,但我不确定如何为多个有关系的表执行此操作。

假设我有 3 个表,一个客户表,一个客户地址表和一个客户购买表。

为客户表做种很容易,因为它是主表,但其他两个表有一个名为 customer_id 的列,它是对客户表的引用。

如果我想使用播种机,我该如何编写代码来获得 X 数量的客户,然后在链接回创建的客户的其他表中进行以下记录。

如果我遗漏了文档中的某些内容,我们深表歉意。

【问题讨论】:

标签: php laravel


【解决方案1】:

首先,您需要在Customer 模型上设置relationship。我假设 Customer 模型与 one-to-manyCustomerAddressCustomerPurchase 模型有关系。

<?php

// app/Customer.php
namespace App;

use Illuminate\Database\Eloquent\Model;

class Customer extends Model
{
    public function addresses()
    {
        return $this->hasMany(CustomerAddress::class);
    }

    public function purchases()
    {
        return $this->hasMany(CustomerPurchase::class);
    }
}

接下来,您需要定义一个model factory

<?php

// database/factories/CustomerFactory.php
use Faker\Generator as Faker;

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

$factory->define(App\CustomerAddress::class, function (Faker $faker) {
    return [
        'address' => $faker->streetAddress,
    ];
});

$factory->define(App\CustomerPurchase::class, function (Faker $faker) {
    return [
        'item' => $faker->word,
        'amount' => $faker->randomFloat(2, 10, 200),
    ];
});

现在您所要做的就是使用这些模型工厂在数据库中植入随机记录。你仍然可以使用 Eloquent 集合和 relationship 就好了:

<?php

// database/seed/DatabaseSeeder.php
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(App\Customer::class, 10)->create()->each(function ($customer) {
            $customerAddresses = factory(App\CustomerAddress::class, 2)->make();
            $customerPurchases = factory(App\CustomerPurchase::class, 5)->make();

            $customer->addresses()->saveMany($customerAddresses);
            $customer->purchases()->saveMany($customerPurchases);
        });
    }
}

希望这能给你一些想法。

【讨论】:

  • 迄今为止最好的解决方案。
【解决方案2】:

文档中的一些修改代码:

$users = factory(Customer::class, 3)
       ->create()
       ->each(function ($u) {
            $u->addresses()->save(factory(Address::class)->make());
            $u->purchases()->saveMany(factory(Purchase::class, 10)->make());
        });

【讨论】:

    【解决方案3】:

    您可以简单地创建一个foreach 声明

    $customers = factory(Customer::class,N)->create();
    foreach( $customers as $customer)
    {
         factory(CustomerAddress::class)->create([
              'customer_id' => $customer->id
         ]);
    
         factory(CustomerPurchase::class)->create([
              'customer_id' => $customer->id
         ]);
    }
    

    注意仅在您希望为每位客户提供地址和购买的情况下才建议这样做。
    否则,您应该区别对待播种,而不是为每个客户提供地址和购买地址。
    这将使您的测试不太可靠

    【讨论】:

    • 是的,我想过为每个人制作一个并用 faker 模拟数据,但认为必须有一种明智的做法
    • 如何在工厂内部使用变量'customer_id'?
    猜你喜欢
    • 1970-01-01
    • 2016-11-17
    • 2020-10-08
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 2016-05-28
    相关资源
    最近更新 更多