【问题标题】:Seed data with relationship in LaravelLaravel中具有关系的种子数据
【发布时间】:2018-11-10 03:23:47
【问题描述】:

我正在尝试通过faker factory 为我的Laravel 5.6 应用程序播种,我通过link 有点困惑,因为我有一些基本的静态数据,例如我有一个公司 型号:

class Company extends Model {

    use SoftDeletes, HasDataSearchTable, HasSlug;

    protected $fillable = [
        'name', 'code_link', 'slug', 'establishment', 'parent_id', 'website', 'updates', 'user_id', 'tracked', 'verified', 'active', 'premium', 'status'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'created_at','updated_at','deleted_at'
    ];

    public function roles()
    {
        return $this->belongsToMany('Noetic\Plugins\Conxn\Models\Variables\Company\Role', 'company_role_relation', 'company_id', 'role_id')->withTimestamps();
    }
}

还有一个关系型角色模型:

class Role extends Model
{
    use SoftDeletes  , HasDataSearchTable;

    protected $table='company_role';

    protected $fillable = [
        'name', 'parent_id'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'created_at','updated_at','deleted_at'
    ];

}

和相应的数据库,我遵循 laravel 约定,现在我要播种数据:

我有一组特定的角色,我是手动播种的,

class CompanyRoleSeed extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        DB::table('company_role')->insert([
            ['name' => 'Contractor', 'parent_id' => null],
            ['name' => 'Consultant', 'parent_id' => null],
            ['name' => 'Manufacturer', 'parent_id' => null],
            ['name' => 'Miscellaneous', 'parent_id' => null],
            ['name' => 'Owner', 'parent_id' => null],
            ['name' => 'Supplier', 'parent_id' => null],
        ]);

    }
}

对于我想创建工厂的公司,我做到了:

$factory->define(Company::class, function (Faker $faker) {


    return [
        'name' => $faker->company,
        'code_link' => rand(5, 10),
        'slug' => str_slug($faker->company),
        'about' => $faker->paragraphs(),
        'establishment' => $faker->randomElement('2015', '2016', '2017', '2018'),
        'parent_id' => $faker->randomElement(null, '1', '2', '3'),
        'website' => $faker->url,
        'user_id' => $faker->randomElement('1', '2', '3', '4', '5'),
        'updates' => $faker->paragraphs(),
        'tracked' => $faker->boolean,
        'verified' => $faker->boolean,
        'active' => $faker->boolean,
        'premium' => $faker->boolean,
        'status' => $faker->randomElement('saved', 'draft')
    ];
});

在公司种子中我有:

class CompanySeed extends Seeder
{
    /**
     * Run the database seeds.
     *
     * @return void
     */
    public function run()
    {
        factory(Company::class, 10)->create()->each(function ($company) {
            $company->roles()->save(); // Don't now how to execute here
        });
    }
}

在$company->roles()->save();的地方帮帮我,我该怎么办。

欢迎任何指导或即兴创作。

【问题讨论】:

    标签: php laravel laravel-seeding


    【解决方案1】:

    在回答你的问题之前,你应该知道 Laravel 的文档解释了如何做 this。

    但为了保存相关模型,您首先需要创建一个假模型,或者在您的情况下关联您已经创建的角色。为了做到这一点,您可以首先使用以下内容创建一个角色工厂:

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

    正如你在我创建的角色工厂中看到的那样,我拉了一个随机角色,因为你说你已经手动创建了它们,所以如果你随机选择一个,那么你的公司将与你的角色之一随机相关!

    一旦您拥有:在数据库中创建的角色、角色工厂,您就可以将随机角色与使用工厂的公司关联起来,以保存随机实例。

    factory(Company::class, 10)->create()->each(function ($company) {
            $company->roles()->save(factory(App\Role::class)->make()); // Don't now how to do here
        });
    

    更新 如果您想为每个公司保存多个角色,您可以这样做:

    factory(Company::class, 10)->create()->each(function ($company) {
            // Instead of 4 you could also create a random number 
            // using $numberOfRolesToAttach = rand($min,$max)
            for($i = 1; $i <= 4; $i++) :
                $company->roles()->save(factory(App\Role::class)->make());
            endfor;
    
        });
    

    【讨论】:

    • 感谢您的更新,但我的角色中没有任何随机元素我有 contractors, consultants, owners 等固定数据。
    • 我知道,这就是为什么它会从顾问、业主、承包商等中随机选择的原因。因为在工厂内你随机抽取其中一个 -> App\Role::all()- >random()->名称
    • 所以你的意思是App\Role::all()-&gt;random()-&gt;name不会创建任何新的假数据,或者不会在Role模型中创建任何重复数据。
    • 它将拉出您手动创建的角色之一,因为您正在选择模型,并且 random() 返回在随机选择的数据库上创建的实例
    • 更新了工厂,现在看起来可能更清晰了
    【解决方案2】:

    您可以查询要分配给公司的角色并将它们与创建的记录相关联,如下所示:

    class CompanySeed extends Seeder
    {
        public function run()
        {
            $contractorRole = Role::whereName('Contractor')->firstOrFail();
            $ownerRole = Role::whereName('Owner')->firstOrFail();
    
            factory(Company::class, 10)->create()->each(function ($company) use ($contractorRole, $ownerRole) {
                $company->roles()->attach([
                    $contractorRole->id,
                    $ownerRole->id
                ]);
            });
        }
    }
    

    相关记录可以查看文档https://laravel.com/docs/5.6/eloquent-relationships#inserting-and-updating-related-models

    【讨论】:

    • 您好,感谢您的回复,我有一个疑问,我在我的公司模型中定义了多对多关系与角色,所以这个saveMany() 可以工作吗?
    • @NitishKumar,我的错,我已经用attach() 更新了多对多的方法。
    • 我可以使用随机收集方法来使用任何值吗,因为在我看来,每次它都会有$contractorRole 和$ownerRole。
    • 为此使用工厂,看看我的回答我已经这样做了:D
    • 或者在每个函数里面拉一个随机的$contractorRole和$ownerRole
    猜你喜欢
    • 2019-08-31
    • 1970-01-01
    • 1970-01-01
    • 2013-06-27
    • 2019-02-13
    • 1970-01-01
    • 2014-01-26
    • 2019-11-14
    • 2013-03-22
    相关资源
    最近更新 更多