0

I have has_and_belongs_to_many relations between two models (Phone and Category) and I seed the phones and categories's tables with something similar to this :

Phone.create(name:'Home', phone:'+00 0 00 00 00 00')
Phone.create(name:'Work', phone:'+00 1 00 00 00 00')
Category.create(name:'tactile-screen')
Category.create(name:'mobile')
Category.create(name:'landline')

This is my schema.rb

create_table "categories", force: :cascade do |t|
  t.string "name"
end

create_table "categories_phones", id: false, force: :cascade do |t|
  t.integer "category_id"
  t.integer "phones_id"
end

create_table "phones", force: :cascade do |t|
  t.string "name"
  t.string "phone"
end

And theses are my models :

class Category < ApplicationRecord
    has_and_belongs_to_many :phones
end
class Phone < ApplicationRecord
    has_and_belongs_to_many :categories
end

I want to seed the belonging categories to each phones, how could I do that ?

Nino
  • 1,217
  • 2
  • 8
  • 13
  • @moveson there is no join model in a `has_and_belongs_to_many` association. Thats `has_many through:` – max Apr 11 '18 at 21:43
  • @moveson I don"t have a "relationship model" Only a table. I've edited my post – Nino Apr 11 '18 at 21:47
  • @NinoTreyssat-Vincent I was confused, thinking you were using a `has_many: through` relationship. See my answer below. – moveson Apr 11 '18 at 21:47

2 Answers2

2

If you want to associate each Phone instance with all the categories you can do it like so:

Category.create(name:'tactile-screen')
Category.create(name:'mobile')
Category.create(name:'landline')

ids = Category.all.ids

Phone.create(name:'Home', phone:'+00 0 00 00 00 00', category_ids: ids)
Phone.create(name:'Work', phone:'+00 1 00 00 00 00', category_ids: ids)

Otherwise just create arrays of the records and you can do something like the following if you for example want to apply a random category:

categories = ['tactile-screen', 'mobile', 'landline'].map do |c|
  Category.create(name: c)
end

phones = [
  Phone.create(name:'Home', phone:'+00 0 00 00 00 00'),
  Phone.create(name:'Work', phone:'+00 1 00 00 00 00')
]

phones.each do |p|
  p.categories << categories.sample
end

If you are using Faker or FFaker you can use this nifty trick to generate random records:

require 'ffaker'

# generate a 100 random numbers
phones = 100.times.map do 
  Phone.create(name:'Home', FFaker::PhoneNumber.phone_number)
end

# generate between 0 and 100 random numbers
phones = ((rand * 100).floor).times.map do
  Phone.create(name:'Home', FFaker::PhoneNumber.phone_number)
end
max
  • 96,212
  • 14
  • 104
  • 165
1

You'll want to assign the newly created records to instance variables like this:

# db/seeds.rb

phone_1 = Phone.create(name:'Home', phone:'+00 0 00 00 00 00')
phone_2 = Phone.create(name:'Work', phone:'+00 1 00 00 00 00')

category_1 = Category.create(name:'tactile-screen')
category_2 = Category.create(name:'mobile')
category_3 = Category.create(name:'landline')

...

Assuming you want to assign each phone to each category, you can let Rails do the work for you like this:

...

[category_1, category_2, category_3].each do |category|
  category.phones << [phone_1, phone_2]
end
moveson
  • 5,103
  • 1
  • 15
  • 32