2011-03-21 7 views
8

레일스 : 여러 조건에 합치다.

class Interest < ActiveRecord::Base 
    has_and_belongs_to_many :user_profiles 
end 

class UserProfile < ActiveRecord::Base 
    has_and_belongs_to_many :interests 
end 

와 같은 간단한 모델이 있습니다. 특정 관심사를 가진 모든 사용자를 쿼리하려면 상당히 간단합니다.

UserProfile.joins(:interests).where('interests.id = ?', an_interest) 

그러나 여러 관심사를 가진 사용자를 어떻게 찾을 수 있습니까? 물론

UserProfile.joins(:interests).where('interests.id = ?', an_interest).where('interests.id = ?', another_interest) 

조인 후에 아무런 행도 동시에 interest.id = an_interest 및 interest.id = another_interest를 가질 수 있기 때문에 항상 빈 결과를 얻습니다.

ActiveRecord에서 "2 개의 (지정된) 관심사를 가진 사용자 목록을 원하십니까?"라는 첫 번째 작업 버전 인

업데이트 (솔루션) Omar Qureshi

 specified_interests.each_with_index do |i, idx| 
     main_join_clause = "interests_#{idx}.user_profile_id = user_profiles.id" 
     join_clause = sanitize_sql_array ["inner join interests_user_profiles interests_#{idx} on 
        (#{main_join_clause} and interests_#{idx}.interest_id = ?)", i] 

     relation = relation.joins(join_clause) 
    end 

답변

4

좋은입니다 - 그것은 표현 같은 OR을의 당신이 할 필요가 무엇

여러가 기입 longhanded 조인이있다

(?)
profiles = UserProfile 
interest_ids.each_with_index do |i, idx| 
    main_join_clause = "interests_#{idx}.user_profile_id = user_profiles.id" 
    join_clause = sanitize_sql_array ["inner join interests interests_#{idx} on 
         (#{main_join_clause} and interests_#{idx}.id = ?)", i] 
    profiles = profiles.join(join_clause) 
end 
profiles 

필요에 맞게 main_join_clause를 변경해야 할 수 있습니다.

+0

그건 내가 바라는 것보다 더 복잡합니다 :)! 그러나 당신은 분명히 나를 올바른 방향으로 가리켰다. 감사. 유일한 차이점은 당신이 쓴 것처럼'inner join interests'보다는'inner join interests_user_profiles'입니다. –

+0

... '관심사 _ # {idx} .id =?'를'관심 _ # {idx} .interest_id =? '로 대체하십시오. –

+0

아 - M 대 M 가입 이었습니까? 그것은 의미가있을 것입니다, 죄송합니다 그 비트를 읽지 못했습니다! :디 –

2

이 지정된 관심사 중 하나 이상이있는 사용자를 받게됩니다.

UserProfile.joins(:interests).where(:id => [an_interest_id, another_interest_id]) 

GE하려면 지정된 관심사를 모두 가진 사용자라면 다음과 같이 할 수 있습니다.

def self.all_with_interests(interest_1, interest_2) 
    users_1 = UserProfile.where("interests.id = ?", interest_1.id) 
    users_2 = UserProfile.where("interests.id = ?", interest_2.id) 

    users_1 & users_2 
end 

놀랍지 만 효율적이지는 않지만 필요한 것은 무엇입니까?

+0

'UserProfile.joins (: 관심사) .where ("interests.id =?", [25, 26])'시도했지만 작동하지 않았습니다. –

+0

아니요, 여전히 작동하지 않습니다. 'SELECT "user_profiles". * FROM "user_profiles"INNER JOIN "interests_user_profiles"ON "interests_user_profiles". "user_profile_id"= "user_profiles". "id"INNER JOIN "관심사" "관심사"에 대한 관심. "id"= "interest_user_profiles". "interest_id"WHERE (interests.id = 25,26)' –

+0

다른 답변에 대한 귀하의 의견을 읽었습니다. 논리적 인 AND가 필요하다는 것을 깨닫지 못했습니다. 내 대답은 OR을 할 것입니다. – Ant

0

IN (?) 및 배열을 시도해보십시오

UserProfile.joins(:interests).where('interests.id IN (?)', [1,2,3,4,5]) 
에서
+1

업데이트 됨 IN 절은 논리적 OR (하나의 관심 또는 다른 쪽 또는 둘 모두 포함) ... 논리적 AND 필요 (모든 관심사가 있음) –

관련 문제