dominikduda
dominikduda

Reputation: 335

Rails 4 how to populate join table using seeds.rb

I'm practicing Rails. I want to have messages and tags for them (There should be many tags for single message and many messages for single tags). I have 2 relevant models: Messages and Tags. They are associated using has_and_belongs_to_many. I'm using ffaker to populate tables

Models:

Message:

class Message < ActiveRecord::Base
  has_many :comments, dependent: :destroy
  has_and_belongs_to_many :tags
end

Tag:

class Tag < ActiveRecord::Base
  has_and_belongs_to_many :messages
end

Migrations:

Messages:

class CreateMessages < ActiveRecord::Migration
  def change
    create_table :messages do |t|
      t.text :content
      t.timestamps
    end
  end
end

Tags:

class CreateTags < ActiveRecord::Migration
  def change
    create_table :tags do |t|
      t.string :title
    end
  end
end

Join table:

class CreateMessagesTagsJoinTable < ActiveRecord::Migration
  def change
    create_table :messages_tags, id: false do |t|
      t.references :tag, index: true
      t.references :message, index: true
    end
  end
end

Seeds file:

5.times { Message.create([content: FFaker::CheesyLingo.paragraph]) }

Message.all.each do |msg|
  rand(4).times { Comment.create([content: FFaker::CheesyLingo.sentence, message_id: msg.id]) }
  2.times { msg.tags.create([title: FFaker::HipsterIpsum.word.gsub(' ','-').downcase]) }
end

Comments are irrelevant. So firstly I'm populating messages table here. Secondly I'm populating tags table from inside of messages. What I end up is populated messages and tags table where every message has 2 tags.

Now, here is the question:

How do I associate already created tags to messages and vice-versa? I know how to do so by creating them, but now I want to associate few tags to single message. I also would like to associate few messages to single, already created tag. How to do that, what is the syntax?

Upvotes: 0

Views: 2344

Answers (1)

Deepak Mahakale
Deepak Mahakale

Reputation: 23671

This should work

Message.all.each do |msg|
  rand(4).times { Comment.create([content: FFaker::CheesyLingo.sentence, message_id: msg.id]) }
  tags = 2.times { msg.tags.create([title: FFaker::HipsterIpsum.word.gsub(' ','-').downcase]) }
  msg.tags = tags
end

or you can do it manually

msg = Message.first
tag = Tag.first
tag.messages << msg
# or
msg.tags << tag

Upvotes: 3

Related Questions