B. Bulpett
B. Bulpett

Reputation: 823

Rails how to seed a table in seeds.rb with data from another table

I have 2 tables in my app with a one-to-one relationship. Here is the schema for the two tables:

    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"

As you can probably tell, there are other tables which relate to these tables. Working from the bottom up, creating Customer objects is the current bottleneck as it is the first table that relies on another for its data.

Here are the models:

  class User < ActiveRecord::Base
      has_one :role
  end

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

This is what I've tried to do in my seeds.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

Users have been generated just fine in my database with this, but now what I need is to assign a unique (not repeated) user_id to each Customer object that is created, based on those user_id's available in the user table. This is how my customers are associated with users (Note there will be different kind of users in the future, not just customers). The constraints have been built, now how do I reference that field (user_id) when creating a Customer object? And how to keep it from re-using a user_id which was already assigned?

I'm sorry if this is a "newb" question, and yes I Googled it to death already. Very thankful for any help!

Upvotes: 1

Views: 2125

Answers (1)

Anthony
Anthony

Reputation: 15967

You could store your 80 users in an array and as you create new customers, simply use one of those. When you loop through to create your customers, I just have a variable i that's an integer that will reference a user from the array.

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

Upvotes: 4

Related Questions