What is the best way to setup my tables and relationships for this use case?
-
02-10-2019 - |
문제
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
해결책
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
다른 팁
This should work.
class User < ActiveRecord::Base
has_many :causes, :through => :cause_users
has_many :campaigns, :through => :campaign_users
# other model stuff
class Cause < ActiveRecord::Base
has_many :users, :through => :cause_users
has-many :campaigns
# other model stuff
class Campaign < ActiveRecord::Base
belongs_to :cause
has_many :users, :through => :campaign_users
# other model stuff
class CampaignUser < ActiveRecord::Base
belongs_to :campaign
belongs_to :user
# other model stuff
class CauseUser < ActiveRecord::Base
belongs_to :cause
belongs_to :user
# other model stuff
has_many :through requires that you create a new model for each of these joins: campaign_users and cause_users, as is shown but it provides more functionality later on than has_and_belongs_to_many.
I would also suggest using better names than :campaign_users and :cause_users so the relationship is more meaningful.
You can make :has_many :through associations between users and campaigns using a join model, and also between users and causes using the another join model. The you can make a :has_many :campaigns association in the causes model, putting a :belongs_to :cause in the campaign model.
But you won't be able to fetch all the users campaigns or causes by User.campaigns.orders or User.order.campaigns. You should make an iteration over the User.campaigns collection or User.causes, fetching Campaign.cause or Cause.capaigns. Or even making a custom SQL query, using joins and conditions to filter information in the joins.