首页 > 解决方案 > 如何组合两个查询而不使其成为 AND 类型查询?

问题描述

我正在构建一个 Rails 5.0 应用程序。在这个应用程序中,我想创建一个查询来获取所有具有活动订阅的用户,然后将它们与获取所有管理员用户的查询合并。我尝试这样做,但新查询使它们成为一个长查询,其中所有条件都需要匹配。这不是我想要的。

就像现在一样,只会找到管理员。我想找到所有匹配的用户,然后在管理员中合并。我是否可能需要同时运行 FULL 查询然后合并它们?

我想运行第一个查询,然后是第二个查询,然后合并它们。

def self.with_active_subscription_and_admins
  active = User.with_active_subscription
  admins = User.admins
  active.merge(admins)
end

运行的实际查询

SELECT  "users".*
FROM "users"
INNER JOIN "subscriptions" ON "subscriptions"."user_id" = "users"."id"
WHERE "subscriptions"."is_active" = true
AND "users"."is_admin" = true
AND (size_min <= 100 AND rooms_min <= 200 AND price_max >= 300)
LIMIT 11

我不能使用这种类型的合并,因为它会产生一个数组

def self.with_active_subscription_and_admins
  User.with_active_subscription + User.admins
end

这是最终查询(如何使用),如果上面的输出是一个数组,那将不起作用

users = User.with_active_subscription_and_admins.where("size_min <= ? AND rooms_min <= ? AND price_max >= ?", size, rooms, price)

User 中使用的范围是

scope :with_active_subscription, lambda {
  joins(:subscription).where(subscriptions: { is_active: true })
} 

我也试过这个,但后来我得到了数组中的副本。我可以做到与众不同吗?这是一个不好的查询吗?

users = User.with_active_subscription.where("size_min <= ? AND rooms_min <= ? AND price_max >= ?", 100, 200, 300)
admins = User.admins.where("size_min <= ? AND rooms_min <= ? AND price_max >= ?", 100, 200, 300)
records = users + admins

标签: ruby-on-rails

解决方案


要在 Ruby(和 Rails)中将对象数组合并在一起,您可以使用如下|符号:

def self.with_active_subscription_and_admins
  active = User.with_active_subscription #=> [#<User id: 1 ...>, ...]
  admins = User.admins #=> [#<User id: 5 ...>, ...]
  admins | active #=> [#<User id: 1 ...>, #<User id: 5 ...>, ...]
end

这样您的with_active_subscription_and_admins方法就会返回合并的数组。


推荐阅读