使用 Laravel 中的工厂为数据透视表播种

问题描述 投票:0回答:4

我是 Laravel 的新手,我正在寻找一种使用 factories 播种数据透视表的好方法。我不想使用普通播种机。我给你看案例:

我有三个表(usersskillsuser_skill)。

users                user_skill                 skills
+----------------+   +----------------------+   +-----------------+
| id  | name     |   | user_id | section_id |   | id  | skills    |
+----------------+   +----------------------+   +-----------------+
| 1   | Alex     |   |         |            |   | 1   | draw      |
|----------------|   |----------------------|   |-----------------|
| 2   | Lucy     |   |         |            |   | 2   | program   |
|----------------|   |----------------------|   |-----------------|
| 3   | Max      |   |         |            |   | 3   | social    |
|----------------|   |----------------------|   +-----------------+
| 4   | Sam      |   |         |            |
+----------------+   +----------------------+

有没有一种好方法可以将用户表的真实

Id
和技能表的真实
Id
用于数据透视表?我想随机进行,但我不想要与任何 id 都不匹配的随机数。我希望 Id 与 usersskills 相匹配。

我不知道如何开始,我正在寻找一个很好的例子。也许是这样的?

$factory->defineAs(App\User::class, 'userSkills', function ($faker) {
    return [
        'user_id' => ..?
        'skills_id' => ..?
    ];
});
php laravel pivot-table factory laravel-seeding
4个回答
18
投票

我不认为这是最好的方法,但它对我有用。

$factory->define(App\UserSkill::class, function (Faker\Generator $faker) {
    return [
        'user_id' => factory(App\User::class)->create()->id,
        'skill_id' => factory(App\Skill::class)->create()->id,
    ];
});

如果您不想只为数据透视表创建模型,您可以手动插入它。

DB::table('user_skill')->insert(
    [
        'user_id' => factory(App\User::class)->create()->id,
        'skill_id' => factory(App\Skill::class)->create()->id,
    ]
);

或者,随机存在的值。

DB::table('user_skill')->insert(
    [
        'user_id' => User::select('id')->orderByRaw("RAND()")->first()->id,
        'skill_id' => Skill::select('id')->orderByRaw("RAND()")->first()->id,
    ]
);

15
投票

对于那些正在使用 laravel 8.x 并正在寻找解决此类问题的人;

在 laravel 8.x 中,你可以使用魔术方法来提供你的枢轴, 例如,如果您在用户模型中有一个名为“userSkills”的 belongsToMany 关系,您应该以这种方式提供数据透视表:

User::factory()->hasUserSkills(1, ['skills' => 'draw'])->create();

您可以在此处找到文档


8
投票

我有一个类似的问题,我在 Laravel 测试中以这种方式解决了。

不需要创建新的 UserSkills 模型:

版本 Laravel 5.7

数据库

users                user_skill                               skills
+----------------+   +------------------------------------+   +-----------------+
| id  | name     |   | user_id | section_id | state_skill |   | id  | skills    |
+----------------+   +------------------------------------+   +-----------------+
| 1   | Alex     |   |         |            |             |   | 1   | draw      |
|----------------|   |----------------------|-------------|   |-----------------|
| 2   | Lucy     |   |         |            |             |   | 2   | program   |
|----------------|   |----------------------|-------------|   |-----------------|
| 3   | Max      |   |         |            |             |   | 3   | social    |
|----------------|   |----------------------|-------------|   +-----------------+
| 4   | Sam      |   |         |            |             |
+----------------+   +----------------------+-------------+

User.php

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Authenticatable
{
    use Notifiable;
    use SoftDeletes;
    
    public function skills()
    {
        return $this->belongsToMany('App\Skill')
                ->withTimestamps()
                ->withPivot('state_skill');
    }
}

DataBaseTest.php

<?php

namespace Tests\Unit;

use Tests\TestCase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Schema;

class DataBaseTest extends TestCase
{

    /**
     * @test
     */    
    public function test_create_user_skill()
    {
       // Create DataBase
       $users = factory(\App\User::class, 1)
           ->create()
           ->each(function ($user) {

                // Create Models Support
                $skill = factory(\App\Skill::class)->create();
                
                // Create Pivot with Parameters
                $user->skills()->attach($skill->id,[
                    'state_skill' => 'ok'
                ]);
 
            });

        // Testing
        // ...
        $this->assertTrue(true);
    }
}

0
投票

使用 Laravel 中的工厂和这个单行程序为数据透视表播种:

Model1::factory(20)->has(Model2::factory())->create();

它创造:

  • 20 Model1记录
  • 20 Model2记录
  • 20 数据透视表记录 (model1_id = model2_id)
© www.soinside.com 2019 - 2024. All rights reserved.