: has_many : through 연관에 조인이있는 범위
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
에 테이블, 그러나 어떤이 가입되어 / 상태를 MeetingParticipations
관련 테이블 current_user
.
이것에 대한 문제는 경우입니다 current_user
및 another_user
두 참가자가 일부 있습니다 Meetings
예를하는 Meetings
결과 집합의 기록이있다 각 참가자에 대해 반환됩니다 hidden
설정 false
. 경우 current_user
한 true
설정 hidden
모두를 위해 Meetings
, 경우 another_user
에 그 같은 회의의에 참여하고 hidden
로 설정 false
, 사람들은 Meetings
에 나타납니다 Meetings.visible
결과 집합.
위에서 언급했듯이 User
인스턴스 에 적절하게 조인 할 범위를 가질 수 있습니까? 그렇지 않은 경우 누군가 이에 대한 해결책을 추천 할 수 있습니까?
이것은 귀하의 문제에 대한 나의 해결책입니다.
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
@user.meetings.visible
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)
이를 수행하는 깨끗한 연결 방법은 다음과 같습니다.
has_many :visible_meetings, -> { merge(MeetingParticipations.visible) },
:source => :meeting, :through => :meeting_participations
좀 더 일반적인 용어로 표현하자면 : 연결 has_many
연결이있는 경우 범위 through
병합을 통해 중간 ( ) 연결 범위를 지정할 수 있습니다 . 아마도 Rails 4+가 필요합니다.
그렇지 않으면 @Paul Pettengill의 답변에서 볼 수 있듯이 (아마도 원치 않는) 중간 범위 연결을 생성하여 수행해야합니다.
다음은 하나의 라이너입니다.
Meeting.joins(:meeting_participations).where(meeting_participation: { hidden: false, user_id: current_user.id })
This is great because you can make a scope out of it, a function out of it, or simply call it anywhere. You can also add any more restrictions you want to the hash.
I know this question was answered a while back but I just encountered a similar issue and was looking around for the best way to handle this. The accepted solution is very simple but I think would be cleaner by moving the scope of the association from Users
to Meeting
as should below
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
scope :hidden, -> { where('meeting_participations.hidden = ?', true) }
scope :visible, -> { where('meeting_participations.hidden = ?', false) }
end
class MeetingParticipations < ActiveRecord::Base
belongs_to :user
belongs_to :meeting
scope :hidden, where(:hidden => true)
scope :visible, where(:hidden => false)
end
With this, you are able to call current_user.meetings.hidden
By design, the meeting now dictates what make it hidden/visible.
It would seem to me that it is not sensible to use a scope on Meeting for your purpose. A meeting itself has no visibility, but the participation has. So I would suggest an extension on the association within User:
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
I hope, this helps.
You could also do:
current_user.meeting_participations.visible.map(&:meeting)
참고URL : https://stackoverflow.com/questions/5856838/scope-with-join-on-has-many-through-association
'Programing' 카테고리의 다른 글
.NET 4.5로 업그레이드 한 후 iFrame 파서 오류 (0) | 2020.11.14 |
---|---|
R에서 참조로 전달할 수 있습니까? (0) | 2020.11.14 |
android 내 자신의 활동을 만들고 확장하는 방법은 무엇입니까? (0) | 2020.11.14 |
직접 실행 창에서 동적으로 인해 'Microsoft.CSharp.RuntimeBinder.Binder'가 정의되지 않았거나 가져온 오류가 발생합니다. (0) | 2020.11.14 |
std :: flush는 어떻게 작동합니까? (0) | 2020.11.14 |