Rails: объединить с несколькими условиями - PullRequest
8 голосов
/ 21 марта 2011

У меня есть простая модель, такая как

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)

, я всегда получаю пустой результат, поскольку после объединения ни одна строка не может одновременно иметь интереса .id = an_interest и интереса.id = another_interest.

есть ли способ в ActiveRecord выразить: «Я хочу, чтобы список пользователей, у которых были связаны 2 (указанные) интересы?»

обновление (решение) это первая рабочая версия, которую я предложил, славаОмар Куреши

    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

Ответы [ 3 ]

4 голосов
/ 21 марта 2011

в (?) Не годится - это выражение, похожее на ИЛИ

, вам нужно будет записать несколько объединений 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 для удовлетворения ваших потребностей.

2 голосов
/ 21 марта 2011

Получат пользователей, у которых есть хотя бы один из указанных интересов.

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

Чтобы получить пользователей с обоими указанными интересами, я бы, вероятно, сделал что-то вроде этого:

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 голосов
/ 21 марта 2011

Попробуйте IN (?) и массив:

UserProfile.joins(:interests).where('interests.id IN (?)', [1,2,3,4,5])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...