2

나는이 내가 가지고 조건부 관계를 기반으로 결과를 보여 테이블을 조인의 값을 연결하기 위해 노력하고있어 ... 그리고 내가 몇 가지 문제 HABTM 관계 및 테이블에 참여

나는이를 데 사용자 모델 (: 이름, : 비밀번호, : 이메일) 및 이벤트 모델 (: 이름, : 등) 및 관심 모델 (: 이름)

각 모델에 약 5 개의 레코드를 만들었습니다.

그런 다음 두 개의 조인 테이블 -> UsersInterests 및 EventsInterests; 각각은 기본 키를 포함하지 않고 user_id/interest_id 및 event_id/interest_id로만 구성됩니다.

가 그럼 난 모델에 추가 I는 사용자의 관심사가 이벤트와 해당 이벤트 만이 작업에서

관심사를 발견 컨트롤러를 만들고 싶었 이제 HABTM 관계

users => has_and_belongs_to_many :interests 
events => has_and_belongs_to_many :interests 
interests => has_and_belongs_to_many :users 
     has_and_belongs_to_many :events 

을 파일 잠시 동안 나는 그런

@Events = Event.User.find([condition]) 
[condition] = where users.interest == event.interest 

또는 무언가의 영역에서 뭔가가 필요하다고 생각했습니다 ... 나는 lost..How의 종류는 당신이 인터넷을 진술 할 수 있어요 상태 ...? 나는 SQL에서 내부 조인을 수행하는 방법을 알고 있지만이 우아한 레일 방법을 찾고 있어요 ... 어떤 팁 얘들 아?

+0

:

@user = User.first; @users = User.find(1,2,3) # @events = all events a single user would be interested in @events = Event.shares_interest_with_users(@user) # @events = all events any of the listed users would be interested in. @events = Event.shares_interest_with_users(@user) 

당신은 심지어 이름이 아직 일어나지 않은 이벤트를 선택하는 범위와 체인 두 가지를 정의 할 수 ? 이벤트는 어떻습니까? – zetetic

+0

관심 분야와 이벤트 모두 많은 관심사를 가질 수 있습니다. – ChrisWesAllen

+0

당신이 얻으려는 목록을보다 명확하게 정의 할 수 있습니까? "사용자 관심이 이벤트 관심사와 일치하는 이벤트 만"에서 특정 사용자 집합을 의미합니까? 아니면 어떤 사용자입니까? – EmFi

답변

7

우아한 루비 방법은 named scopes입니다. 그러나 관계를 통해 has_many : 대신에 has_and_belongs_to_many 관계를 사용하기로 결정 했으므로 원시 SQL을 사용하여 조인을 정의해야합니다. 이는 매우 우아하지 않습니다. Rails가 SQL 생성을 처리하는 방식 때문에 단일 사용자와 함께 사용 범위를 만들고 여러 사용자와 함께 사용할 두 번째 명명 된 범위를 만들어야합니다.

: 사용자의 목록에 관심이있을 수있는 모든 이벤트를 얻을

@events = Event.shares_interest_with_user(@user) 

또는이 : 당신이 모든 이벤트를 얻기 위해이 작업을 수행 할 수 있습니다 지금

Class Event < ActiveRecord::Base 
    ... 

    #find events that share an interest with a single user 
    named_scope :shares_interest_with_user, lambda {|user| 
    { :joins => "LEFT JOIN events_interests ei ON ei.event_id = events.id " + 
     "LEFT JOIN users_intersets ui ON ui.interest_id = ei.interest_id", 
     :conditions => ["ui.user_id = ?", user], :group_by => "events.id" 
    } 

    #find events that share an interest with a list of users 
    named_scope :shares_interest_with_users, lambda {|users| 
    { :joins => "LEFT JOIN events_interests ei ON ei.event_id = events.id " + 
     "LEFT JOIN users_intersets ui ON ui.interest_id = ei.interest_id", 
     :conditions => ["ui.user_id IN ?", users], :group_by => "events.id" 
    }  
    } 

    #find events that share an interest with any user 
    named_scope :shares_interest_with_any_user, lambda { 
    { :joins => "LEFT JOIN events_interests ei ON ei.event_id = events.id " + 
     "JOIN users_intersets ui ON ui.interest_id = ei.interest_id", 
     :conditions => "ui.user_id IS NOT NULL", :group_by => "events.id" 
    }  
    } 

end 

사용자가 관심을 가질만한

@events = Event.shares_interest_with_users(@users) 

그러나 내가 경고했듯이 그것은 실제로 이 아닙니다.

HABTM 관계 대신 적절한 조인 모델과의 관계를 통해 관계를 has_many로 재정의하면 조인을 크게 단순화 할 수 있습니다. 귀하의 경우에는 nested has many through plugin이 필요합니다. N.B. 다른 모든 모델에 해당하는 has_many/belongs_to 문을 추가해야합니다. 심지어 조인 모델.

이제 다음이 작동합니다. 사용자가 하나 명의 관심이나 많이 가질 수

named_scope :future_events, lambda { 
    { :conditions => ["start_time > ?", Time.now]} 
} 

Events.future_events #=> Events that haven't started yet. 

# Events that a user would be interested in but only choose those 
# that haven't started yet. 
Events.future_events.shares_interest_with_user(@user) 
+0

질문이 약간 모호했습니다. 따라서 귀하의 질문을 오해 한 경우 알려 주시면 솔루션을 업데이트하겠습니다. 문제를 올바르게 이해했는지 여부에 관계없이 명명 된 범위가 문제를 해결하는 가장 좋은 방법 일 수 있습니다. – EmFi

+0

그게 진짜로 내가 뭘 하려는지 많은 것으로 보인다 ... 내가 뭔가를 찾고 있었어 @events = Event.find (: all, : conditions => {: users_interests == : events_interests }) 하지만 오류 => "해시에 대한 홀수 번호 목록"이 표시됩니까? – ChrisWesAllen

+0

'{: user_interests == : events_interests}'는 SQL에서도 절대 의미가 없습니다. 우선 유효한 해시가 아닙니다. 두 번째로 : users_interests와 : events_interests는 명시 적으로 테이블을 조인하지 않는 한 find 조건으로 주어질 때 모두 유효하지 않은 해시 키입니다. – EmFi

관련 문제