Activerecord has_many :through through multiple models

你说的曾经没有我的故事 提交于 2019-12-10 03:59:46

问题


I'm trying to access all comments from a given user with user.comments. The query is to go through two different models, which likely both return results. My relations are set up as follow:

class User < ActiveRecord::Base
  has_many :organisers
  has_many :participants
  has_many :comments, through: :participants / :organisers (see explenation below)
end

class Organiser < ActiveRecord::Base
  belongs_to :user
end

class Participant  < ActiveRecord::Base
  belongs_to :user
end

class Comment < ActiveRecord::Base
  belongs_to :organiser
  belongs_to :participant
end

A comment is validated to belong to either a participant, or an organiser.

I'm not sure how to go about this. I've tried

has_many :comments, through: :participants
has_many :comments, through: :organisers

and

has_many :comments, through: [:organisers, :participants]

But that last one isn't rails. Is there a proper way to do this? Thanks!


回答1:


Since we couldn't use has_many, through here because comments come from both of organisers and participants. I just think there are 2 solutions here:

Solution #1 Define comments method:

class User < ActiveRecord::Base
  def comments
    Comment.joins([{organiser: :user}, {participant: :user}])
           .where(users: {id: self.id})
  end
end

So then your query to find comments is:

User.first.comments

Solution #2 Use scope in Comment

class Comment < ActiveRecord::Base
  scope :from_user, -> (user) { 
    joins([{organiser: :user}, {participant: :user}]).where(users: {id: user.id}) 
  }
end

So your query will be like:

user = User.first
comments = Comment.from_user(user)



回答2:


Could you do something as simple as:

has_many :comments, -> { joins(:participant, :organizer) }, class_name: 'Comment'

This should return all comments that have a Participant or Organizer User, since Rails tends to default joins to an inner join. You may not even need that :class_name argument.




回答3:


I found a solution after many tries. You can use a scope with param in your last has_many sentence in the User model:

has_many :comments, -> (user) {where organiser: user.organisers}, through: :participants

The "user" param represet the User object whom is calling the comments method.




回答4:


I believe your associations would be confused, as user.comments wouldn't know whether it's going through Participant or Organiser, so the best option would be to declare two different joins (with different names):

http://guides.rubyonrails.org/association_basics.html#self-joins



来源:https://stackoverflow.com/questions/36749740/activerecord-has-many-through-through-multiple-models

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!