views:

466

answers:

3

I'm a beginning to ROR, but here's what I'm trying to achieve. I have two items I want to associate: matters and people. Each matter can have many people. That is, I want to create people and matters separately and later be able to link them.

For example, I may create: Bill Clinton Barack Obama

I may create the matters: Global warming War on terror

I want to be able to associate the users Bill Clinton AND Barack Obama to BOTH matters. Can someone point me to a tutorial that can show me how to do this?

+1  A: 

You need a many2many relationship between these two entities.

  • A matter can be studied by many people
  • A person can studie several matters

Rails uses the has_and_belongs_to_many helper to do that. You'll find more about that in the documentation and many many blog posts!

has_and_belongs_to_many helper

reto
A: 
class Politician < ActiveRecord::Base
  has_and_belongs_to_many :tasks
end

class Task < ActiveRecord::Base
  has_and_belongs_to_many :politicians
end

What you need are 3 tables: politicians, tasks and politicians_tasks (having the two columns politician_id and task_id, no primary key)

Hope this helps Seb

flitzwald
+3  A: 

I think has_and_belongs_to_many is used less and less by the RoR community now. While still supported, I think it is now more common to have an intermediate model (in your case something like PoliticianMatter) to join your Politician and Matter models.

Then your politician_matter table will have a PK, a politician_id and a matter_id.

Then you have

class PoliticanMatter < ActiveRecord::Base
  belongs_to :politician
  belongs_to :matter
end

The advantage of this approach is that if there ever need to be future properties of the politician -> matter relationship (e.g importance, date of last occurrence) you have a model which affords this - has_and_belongs_to_many would not support the addition of these extra properties.

You can also access the many to many relationship directly from the Politician and Matter models like this

class Politician < ActiveRecord::Base
  has_many :politician_matters
  has_many :matters, :through => :politician_matters
end

class Matter < ActiveRecord::Base
  has_many :politician_matters
  has_many :politicians, :through => :politician_matters
end
DanSingerman