【问题标题】:Better way of Seeding a Pivot Table播种数据透视表的更好方法
【发布时间】:2014-05-02 16:52:21
【问题描述】:

我有以下表格 usersroles 和具有以下表格结构的数据透视表 role_user

用户

  • 身份证
  • 用户名
  • 密码

角色

  • 身份证
  • 角色

角色用户

  • 身份证
  • role_id
  • user_id

        <?php
             class PivotTableSeeder extends Seeder {
                 public function run()
                 {
                  // Seeds the roles table
                    DB::table('roles')->delete();
    
                    DB::table('role_user')->insert(array(
                    array('user_id' => 1, 'role_id' => 1),
                    array('user_id' => 2, 'role_id' => 2),
                    array('user_id' => 3, 'role_id' => 1),
                    array('user_id' => 3, 'role_id' => 3),
                    array('user_id' => 3, 'role_id' => 5)
                ));
                }
            }
    

数据透视表使用DB select播种

有没有更好的方法来播种表格,包括数据透视表?

我在想,也许当我为 users 表播种时,它也会为 role_user 表播种,而不是手动将数据插入数据透视表。

例子:

角色

  • id = 1
  • 角色 = 编码器
  • id = 2
  • 角色 = 技术
  • id = 3
  • 角色 = 销售

用户

  • id = 1
  • 用户名 = 用户
  • 密码=通过
  • id = 2
  • 用户名 = user2
  • 密码 = pass2

角色用户

  • id = 1
  • user_id = 1
  • role_id = 1
  • id = 2
  • user_id = 1
  • role_id = 2
  • id = 3
  • user_id = 2
  • role_id = 3

编辑

我正在使用这个 Eloquent 播种我的用户表。 无论如何,在播种用户时,role_user 也会得到更新?

User::create(array(
    'id' => '1',
    'username' => 'user',
    'password' => 'pass'
));
User::create(array(
    'id' => '2',
    'username' => 'user2',
    'password' => 'pass2'
));

【问题讨论】:

    标签: laravel laravel-4 pivot-table


    【解决方案1】:

    你可以试试这个(假设你已经播种了角色):

    $user = User::create(['id' => '1', 'username' => 'user', 'password' => 'pass']);
    $user->roles()->sync([1,2]); // array of role ids
    
    $user = User::create(['id' => '2', 'username' => 'user2', 'password' => 'pass2']);
    $user->roles()->sync([3,4]); // array of role ids
    

    我使用了[] 而不是array(),如果你的PHPver-5.4 之前,那么你应该使用array()

    【讨论】:

    • 这不是创建角色,attach() 不是将您限制为一条记录吗?所以你必须运行多个插入来为一个用户添加多个角色?
    • 已经根据他的代码创建了角色,只附加了创建的角色。
    • 我在想他想为每个用户附加一个角色,但对于多个角色应该使用sync,谢谢@ollieread :-)
    • @WereWolf-TheAlpha 只是想知道,我使用您的答案为数据库播种,我注意到 created_atupdated_at 列没有更新?
    • 跟播种无关。
    【解决方案2】:

    出于测试目的,我使用如下非常简单快速的方法。

    假设我们有带有数据透视表的用户和类别(顺便说一句,这来自 JeffreyWay 的生成器):

    <?php
    
    // Composer: "fzaninotto/faker": "v1.3.0"
    use Faker\Factory as Faker;
    
    class UsersTableSeeder extends Seeder {
    
        public function run()
        {
            $faker = Faker::create();
    
            foreach(range(1, 100) as $index)
            {
                User::create([
                    'username'   => $username = $faker->userName,
                    'email'      => $faker->email,
                    'password'   => Hash::make($username),
                    'account_id' => $index
                ]);
            }
        }
    
    }
    
    // all other seeders look the same, so I paste just the code that matters:
    // Categories
        foreach(range(1, 30) as $index)
        {
            Category::create([
                'name' => $faker->word
            ]);
        }
    
    // pivot table
        foreach(range(1, 50) as $index)
        {
            DB::table('category_user')->insert([
                'category_id' => rand(1,30),
                'user_id' => $faker->unique()->randomNumber(1, 100)
            ]);
        }
    

    【讨论】:

    • 但是它可以生成包括关系吗?如果这听起来很傻,我很抱歉,但我不熟悉使用 Faker。
    • 它无法自动生成它,但正如您在我的示例中看到的那样,它需要 2 行简单的代码:从 1 到 max 的随机 id,其中 max 是硬编码的。确实,以这种方式播种几张桌子大约需要 5 分钟。
    【解决方案3】:

    对于 n:m 关系,我需要附加随机条目,我使用这个简单但高效的 Seeder 代码,它只使用真实的 id:

        $faker = Faker\Factory::create();
    
        $limit = 100;
    
        for ($i = 0; $i < $limit; $i++) {
            $newrow = *Yourmodel*::create ([
                'email' => $faker->word . rand(0, 9999) . '@test.com' ,
              ...
            ]);
    
            $ids = $faker->randomElements( \App\YourOtherModel::select('id')->get()->toArray(), rand(1,*3*) );
            foreach($ids as $id) {
                $newrow->*your_relationship*()->attach( $id );
       }
    

    【讨论】:

      【解决方案4】:

      我不确定其他人对此有何看法,但在为数据库播种时,我喜欢使用实际模型进行播种,这样您就可以使用插入相关模型所附带的所有便捷功能。

      如果您使用预定义的 ID 为用户和角色播种,那么这很容易。

      class UserSeeder extends Seeder
      {
      
          public function run()
          {
              DB::table('users')->truncate();
              DB::table('roles')->truncate();
              DB::table('user_roles')->truncate();
      
              $users = [];
      
              $user = User::create(['id' => 1, 'blah' => 'honk']);
              $users[$user->id] = $user;
              $user = User::create(['id' => 2, 'blah' => 'honk']);
              $users[$user->id] = $user;
              // etc etc
      
              $roles = [];
              $role = Role::create(['id' => 1, 'blah' => 'honk']);
              $roles[$role->id] = $role;
              // etc etc
      
              $user[1]->roles()->sync(1);
              $user[2]->roles()->sync(2);
              $user[3]->roles()->sync(1, 3, 5);
          }
      
      }
      

      在我最近编写的一个应用程序中,我创建了一个播种器,它创建 ACL 组,然后创建权限,将权限分配给特定组,然后随机创建 10-30 个(使用rand)用户并随机分配他们到不同的群体。

      如果有什么不清楚的地方请告诉我。

      【讨论】:

      • 优秀。用户也被播种了吗?例如,这是完全随机的测试数据还是生产就绪数据?
      • 是的,用户正在播种,这仅用于测试数据。
      猜你喜欢
      • 1970-01-01
      • 2020-08-04
      • 2017-09-19
      • 2017-02-10
      • 2017-02-01
      • 2021-06-11
      • 2017-03-14
      • 2021-09-27
      • 1970-01-01
      相关资源
      最近更新 更多