join的范围:has_many:通过关联
class Users < ActiveRecord::Base has_many :meetings, :through => :meeting_participations has_many :meeting_participations end class Meetings < ActiveRecord::Base has_many :users, :through => :meeting_participations has_many :meeting_participations end class MeetingParticipations < ActiveRecord::Base belongs_to :user belongs_to :meeting scope :hidden, where(:hidden => true) scope :visible, where(:hidden => false) end
hidden
是在m2m关联表内的一个额外的布尔列。 给定一些Users
实例current_user
,我想要做的
current_user.meetings.visible
它将检索Meetings
一个集合,其中用户是hidden
列为false
的参与者。 我最近得到的是将以下范围添加到Meetings
类
scope :visible, joins(:meeting_participations) & MeetingParticipation.visible
该scope
Meetings
根据MeetingParticipations
表进行Meetings
筛选,但是没有针对与current_user
相关的MeetingParticipations
表的MeetingParticipations
/条件。
问题在于,如果current_user
和another_user
都是某个Meetings
实例的参与者,则会为每个hidden
设置为false
参与者返回结果集中的Meetings
logging。 如果current_user
对于所有Meetings
都设置为hidden
,则如果another_user
是hidden
设置为false
那些Meetings
的参与者,则这些Meetings
将显示在Meetings.visible
结果集中。
是否有可能有一个范围,因为我已经提到上面将正确joinUser
实例? 如果没有,有人可以推荐一个解决scheme呢?
这是我的解决scheme,您的问题:
class User < ActiveRecord::Base has_many :meeting_participations has_many :meetings, :through => :meeting_participations do def visible where("meeting_participations.visible = ?", true) end end end
在Rails 4中,你可以在关联本身中指定最初在子对象中定义的范围。 简而言之:您无需了解用户模型中的MeetingParticipation模型的内部结构。
class User < ActiveRecord::Base has_many :meeting_participations has_many :meetings, :through => :meeting_participations has_many :visible_participations, -> { visible }, :class_name => 'MeetingParticipation' has_many :visible_meetings, :source => :meeting, :through => :visible_participations end class Meeting < ActiveRecord::Base has_many :meeting_participations has_many :users, :through => :meeting_participations end class MeetingParticipation < ActiveRecord::Base belongs_to :user belongs_to :meeting scope :hidden, -> { where(:hidden => true) } scope :visible, -> { where(:hidden => false) } end
这将允许你做: user1.visible_meetings
和user2.visible_meetings
与不同的结果集
current_user.meetings.merge(MeetingParticipations.visible)
这里是一个单行的:
Meeting.joins(:meeting_participations).where(meeting_participation: { hidden: false, user_id: current_user.id })
这很好,因为你可以把它作为一个function,或者只是把它叫做任何地方。 你也可以添加任何你想要的哈希的限制。
你也可以这样做:
current_user.meeting_participations.visible.map(&:meeting)
在我看来,为了您的目的而使用会议的范围是不明智的。 会议本身没有可见性,但参与已经。 所以我会build议在用户关联的扩展:
class User < ActiveRecord::Base has_many :meetings, :through => :meeting_participations do def visible ids = MeetingParticipation. select(:meeting_id). where(:user_id => proxy_owner.id, :visible => true). map{|p| p.meeting_id} proxy_target.where("id IN (?)", ids) end end ... end
我希望这有帮助。