Search code examples
ruby-on-railsrubymodelsrelationships

What is the best way to setup my tables and relationships for this use case?


1)A user can have many causes and a cause can belong to many users.

2)A user can have many campaigns and campaigns can belong to many users. Campaigns belong to one cause.

I want to be able to assign causes or campaigns to a given user, individually. So a user can be assigned a specific campaign. OR a user could be assigned a cause and all of the campaigns of that cause should then be associated with a user.

Is that possible? And could I set it up so that the relationships could be simplified like so:

User.causes = all causes that belong to a user

User.campaigns = all campaigns that belong to user whether through a cause association or campaign association


Solution

  • I believe you should use the following:

    class User < ActiveRecord::Base
       has_and_belongs_to_many :causes
       has_and_belongs_to_many :campaigns
    end
    
    class Cause < ActiveRecord::Base
       has_and_belongs_to_many :users
       has_many :campaigns
    end
    
    class Campaign < ActiveRecord::Base
       has_and_belongs_to_many :users
       belongs_to :cause
    end
    

    This way you can use

    User.causes
    User.campaigns
    
    Cause.campaing
    Cause.users
    
    Campaign.users
    Campaign.cause
    

    You can read here about has_and_belongs_to_many relationship, here about has_one and here about belongs_to.

    Let me know if this is what you want :]

    Edit:

    "I would still need User.campaigns to be campaigns from a user's causes or individual campaigns associated with a user"

    You can have a method on users model that returns all campaigns. Something like this:

    def all_campaigns
       self.campaigns + self.causes.collect{ |c| c.campaigns }
    end