Rails:以多个条件连接

发布于 2024-10-23 22:15:23 字数 1119 浏览 2 评论 0原文

我有一个简单的模型,例如

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

I have a simple model like

class Interest < ActiveRecord::Base
  has_and_belongs_to_many :user_profiles
end

class UserProfile < ActiveRecord::Base
  has_and_belongs_to_many :interests
end

When I want to query all the users with a specific interests, that's fairly simple doing

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

But how can I look for users who have multiple interests? Of course if I do

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

I get always an empty result, since after the join, no row can have simultaneously interest.id = an_interest and interest.id = another_interest.

Is there a way in ActiveRecord to express "I want the list of users who have 2 (specified) interests associated?

update (solution) that's the first working version I came up, kudos to 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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

避讳 2024-10-30 22:15:23

in (?) 不好 - 它是一个类似 OR 的表达式

,您需要做的是手动编写多个连接

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 以满足您的需要。

in (?) is no good - it's an OR like expression

what you will need to do is have multiple joins written out 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

You may need to change the main_join_clause to suit your needs.

囚我心虐我身 2024-10-30 22:15:23

这将获得至少具有其中一项指定兴趣的用户。

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

效率不是很高,但它应该满足您的需要?

This will get users that have at least one of the specified interests.

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

To get users that have both of the specified interests I'd probably do something like this:

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

Not amazingly efficient, but it should do what you need?

∞梦里开花 2024-10-30 22:15:23

尝试 IN (?) 和一个数组:

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

Try IN (?) and an array:

UserProfile.joins(:interests).where('interests.id IN (?)', [1,2,3,4,5])
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文