BEGINNER: Correct seeds.rb in rails 3

I've just created two models and one "join table". Person, Adress (create_adresses_personss)

class Person < ActiveRecord::Base
  has_and_belongs_to_many :streets
end

class Street < ActiveRecord::Base
  has_and_belongs_to_many :persons
end

Now I want to add some data to these models in the db/seeds.rb file. The tutorial I follow just adds the objects:

person = Person.create :name => 'Dexter'

street.create[{:streetname => 'street1'},
            {:streetname => 'street2'},
            {:streetname => 'julianave'},
            {:streetname => 'street3'}]

Question 1: Why is persons' data added differently than streets'? Is it just the tutorial that wants to show that there are many ways of adding data in the seeds.rb?

Question 2: The tutorial doesn't make the connections/joins in the seeds.rb. It does that in the rails console;

>>p1 = Person.find(1) 
>>s1 = Street.find(1) 
>>p1.streets << s1 

Can't theese connections be made in the seeds.rb file?

Question 3: Would it be better to do this join with a "rich many_to_many-assocciation"?

Thanks for your time and patience with a beginner ;)

Upvotes: 3

Views: 4063

Answers (2)

Cluster
Cluster

Reputation: 5617

One way that I like to create seed data for many-to-many associations is setting up one of the models, the adding a tap block that sets up the other models through the association.

Person.create!(:name => "Fubar").tap do |person|
  3.times do |n|
    person.streets.create!(:streetname => "street #{n}")
  end
  # OR
  person.streets.create!([
    {:streetname => "street 1"},
    {:streetname => "street 2"},
    ... and so on
  ])
end

All tap is doing is executing the block with the object as it's only parameter. I find it convenient for seeds.

One other tip I would toss out there would be to have your model attribute names spaced on the words with underscores.

:street_name instead of :streetname

The difference is more profound when you start wanting to use some of the ActiveSupport helers that take model attributes and turn them into text strings for use in the UI. e :streetname.to_s.titleize # "Streetname" :street_name.to_s.titleize # "Street Name"

And one last nitpick, you might want your join table to be addresses_people not addresses_persons since the rais inflector is going to pluralize person as people. The same would go for your controller on the Person model, PeopleController instead of PersonsController. Though maybe it will work with persons as well.

:person.to_s.pluralize # "people"
:people.to_s.singularize # "person"
:persons.to_s.singularize # "person"

Upvotes: 2

bricker
bricker

Reputation: 8941

1) The first method is creating one object. The second method is creating multiple objects. However, for the second method you would need to do Street.create, not street.create.

2) Yes, you can do that in the seed file the same way.

3) The "Rich many-to-many" you're talking about is an association with a Join Model, I guess you're talking about. This is opposed to just a join table, which is what has_and_belongs_to_many does. To use a join model, you'll want to look up has_many :through. It's generally considered better to always use a proper join model, however I still use HABTM when I just need a quick, simple association. has_many :through allows for more options and more flexibility, but it is a little more complicated to setup (not that much, though). It's your decision.

Upvotes: 3

Related Questions