Friday, May 6, 2011

Ruby On Rails Relationships - One to Many

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?

From stackoverflow
  • 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

  • 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

  • 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
    

0 comments:

Post a Comment