2011-05-02 133 views
52
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,我想要做的連接範圍:has_many:關聯

current_user.meetings.visible 

將檢索Meetings一個集合,它的用戶是參與者,其中hiddenfalse。我已經得到最接近的是添加以下範圍的Meetings

scope :visible, joins(:meeting_participations) & MeetingParticipation.visible 

scope並過濾MeetingsMeetingParticipations表,但沒有加入對相關current_userMeetingParticipations表/條件。

這樣做的問題是,如果current_useranother_user都是參加一些Meetings例如,Meetings記錄結果集中將返回對於具有hidden設置爲false每個參與者。如果current_userhiddentrue爲所有Meetings,如果another_user在任何與hidden設置爲false那些相同的會議的參與者,這些Meetings將出現在Meetings.visible結果集。

是否可以像上面提到的那樣能夠正確加入User實例?如果不是,有人可以推薦一個解決方案嗎?

+0

大問題! – deivid 2015-03-17 15:32:44

回答

69

這是我對你的問題的解決方案:

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 
+0

謝謝你,絕對是更簡單的答案。 – deefour 2012-03-03 16:15:34

+1

任何人都有在這種情況下投入一些急切的加載的建議?就像一場會議屬於一個場地,我想要加載這些會議? – 2013-10-10 16:48:00

+0

所以我想這工作:includes([:assoc1,:assoc2])。其中.... geez我想我肯定我已經嘗試過,在評論之前。 – 2013-10-11 21:46:57

-3

在我看來,在您的目的上使用會議範圍是不明智的。會議本身沒有可見性,但參與已經。因此,我想用戶之內建議對聯想的延伸:

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 

我希望這有助於。

50

在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_meetingsuser2.visible_meetings有不同的結果集

+6

我喜歡這個解決方案,但爲了讓它起作用,我還需要添加:source到:visible_meetings has_many:visible_meetings,class_name:'Meeting',through::visible_participations,source :: meeting – 2014-09-20 04:13:21

+0

Does' - > {可見}'需要更改爲符號' - > {:可見}'或者上面的代碼片段是否工作正常? – chaostheory 2014-10-06 03:46:58

+2

@ chaostheory對於遲到的回覆感到抱歉,但就其本身而言,它不是一個符號。 – 2015-03-09 00:35:07

6
current_user.meetings.merge(MeetingParticipations.visible) 
0

這裏是一個班輪:

Meeting.joins(:meeting_participations).where(meeting_participation: { hidden: false, user_id: current_user.id }) 

這是偉大的,因爲你可以做一個範圍之它的功能,或者只是在任何地方調用它。你也可以添加任何你想要的哈希的限制。

-3

你也可以這樣做:

current_user.meeting_participations.visible.map(&:meeting)