Rails如何使用来自另一个表的数据在seeds.rb中播种表

时间:2015-02-17 18:15:23

标签: mysql ruby ruby-on-rails-4 activerecord foreign-keys

我的应用中有2个表,一对一的关系。以下是两个表的架构:

    create_table "users", primary_key: "user_id", force: true do |t|
      t.string  "user_username", limit: 30, null: false
      t.string  "user_password", limit: 30, null: false
      t.integer "roles_role_id", limit: 1,  null: false
    end

    add_index "users", ["roles_role_id"], name: "fk_users_roles1_idx", using: :btree
    add_index "users", ["user_id"], name: "user_id", unique: true, using: :btree
    add_index "users", ["user_username"], name: "user_username_UNIQUE", unique: true, using: :btree

    create_table "customers", primary_key: "customer_id", force: true do |t|
      t.string  "cust_email",     limit: 75
      t.string  "cust_phone1",    limit: 20
      t.string  "cust_phone2",    limit: 20
      t.string  "cust_title",     limit: 4
      t.string  "cust_firstname", limit: 40
      t.string  "cust_lastname",  limit: 40
      t.integer "users_user_id",             null: false
    end

    add_index "customers", ["cust_lastname", "cust_firstname"], name:"NAME_LAST_FIRST", using: :btree
    add_index "customers", ["users_user_id"], name: "fk_customers_users1_idx", using: :btree

    add_foreign_key "customers", "users", name: "customers_users_user_id_fk", column: "users_user_id", primary_key: "user_id"
    add_foreign_key "customers", "users", name: "fk_customers_users1", column: "users_user_id", primary_key: "user_id", dependent: :delete, options: "ON UPDATE CASCADE"

    add_foreign_key "users", "roles", name: "fk_users_roles1", column: "roles_role_id", primary_key: "role_id", dependent: :delete, options: "ON UPDATE CASCADE"
    add_foreign_key "users", "roles", name: "users_roles_role_id_fk", column: "roles_role_id", primary_key: "role_id"

正如您可能知道的那样,还有其他表与这些表相关。从下到上,创建Customer对象是当前的瓶颈,因为它是第一个依赖于另一个对象来获取数据的表。

以下是模型:

  class User < ActiveRecord::Base
      has_one :role
  end

  class Customer < ActiveRecord::Base
      belongs_to :user
      has_one :address
      has_many :accounts
  end

这是我在我的种子中尝试做的事情.rb:

  # Generate 80 users (with "customer" role) (Admins created separately)
  80.times do
      username = "#{Faker::Hacker.ingverb}#{Faker::Hacker.noun}#{rand(99)}"
      u = User.new
          u.user_id = SecureRandom.random_number(999999999)
          u.user_username = username
          u.user_password = SecureRandom.base64(12)
          u.roles_role_id = 2
      u.save
  end

  # Generate 80 customers
  80.times do
      c = Customer.new
          firstname = "#{Faker::Name.first_name}"
          lastname = "#{Faker::Name.last_name}"
          user_id = User.select(:user_id).distinct

          c.customer_id = SecureRandom.random_number(999999999)
          c.cust_email = "#{Faker::Internet.free_email(firstname)}"
          c.cust_phone1 = "#{Faker::PhoneNumber.phone_number}"
          c.cust_phone2 = "#{Faker::PhoneNumber.cell_phone}"
          c.cust_title = "#{Faker::Name.prefix}"
          c.cust_firstname = firstname
          c.cust_lastname = lastname
          c.users_user_id = user_id
      c.save
  end

用我的数据库生成的用户就好了,但现在我需要的是根据用户可用的user_id为每个创建的Customer对象分配一个唯一的(不重复的)user_id。表。这就是我的客户与用户的关联方式(注意将来会有不同类型的用户,而不仅仅是客户)。已经构建了约束,现在如何在创建Customer对象时引用该字段(user_id)?以及如何防止它重新使用已经分配的user_id?

对不起,如果这是&#34; newb&#34;问题,是的,我已经用谷歌搜索了它。非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

您可以将80个用户存储在一个阵列中,当您创建新客户时,只需使用其中一个。当您循环创建客户时,我只有一个变量i,它是一个引用数组中用户的整数。

users = []
  80.times do
      username = "#{Faker::Hacker.ingverb}#{Faker::Hacker.noun}#{rand(99)}"
      u = User.new
          u.user_id = SecureRandom.random_number(999999999)
          u.user_username = username
          u.user_password = SecureRandom.base64(12)
          u.roles_role_id = 2
      u.save
      users << u
  end

  # Generate 80 customers
  80.times do |i|
      c = Customer.new
          firstname = "#{Faker::Name.first_name}"
          lastname = "#{Faker::Name.last_name}"

          c.users_user_id = users[i].user_id
          c.customer_id = SecureRandom.random_number(999999999)
          c.cust_email = "#{Faker::Internet.free_email(firstname)}"
          c.cust_phone1 = "#{Faker::PhoneNumber.phone_number}"
          c.cust_phone2 = "#{Faker::PhoneNumber.cell_phone}"
          c.cust_title = "#{Faker::Name.prefix}"
          c.cust_firstname = firstname
          c.cust_lastname = lastname
      c.save
  end