如何取消join / eager_load中的default_scope?

时间:2016-12-01 12:18:25

标签: ruby-on-rails ruby activerecord

我有两种模式:

class User
  default_scope -> { where(deleted_at: nil) }
end

class Order 
  belongs_to :user
end

我希望获得已删除或未删除用户的订单:

Order.joins(:user).merge(User.unscoped)
Order.joins(:user).merge(User.unscope(where: :deleted_at))
# SELECT  "orders".* FROM "orders" 
# INNER JOIN "users" ON "users"."id" = "orders"."user_id" AND "users"."deleted_at" IS NULL 
# ORDER BY "orders"."id" DESC LIMIT 1

Order.eager_load(:user).merge(User.unscoped)
Order.eager_load(:user).merge(User.unscope(where: :deleted_at))
# SELECT  "orders"."id" AS t0_r0, "orders"."user_id" AS t0_r1, 
# "users"."id" AS t1_r0, "users"."deleted_at" AS t1_r1 FROM "orders" 
# LEFT OUTER JOIN "users" ON "users"."id" = "orders"."user_id" AND "users"."deleted_at" IS NULL 
# ORDER BY "orders"."id" DESC LIMIT 1

这些都不起作用。

每个查询都会添加" AND"用户"。" deleted_at" IS NULL"加入声明。

如果我指定关联范围,则没有任何变化:

class Order
  belongs_to :user, -> { unscoped } 
end

但是包含按预期工作:

Order.includes(:user).merge(User.unscoped).last
# SELECT  "orders".* FROM "orders" ORDER BY "orders"."id" DESC LIMIT 1
# SELECT "users".* FROM "users" WHERE "users"."id" = 1054

如何在连接中使用rails来取消关联?

3 个答案:

答案 0 :(得分:1)

你可以这样试试。它适用于Rails 3,但不确定Rails 4。

User.unscoped { Order.joins(:user) }

答案 1 :(得分:0)

我通过手动编写连接查询解决了这个问题。对于您的情况,它应该看起来像:

Order.joins('INNER JOIN users ON users.id=orders.user_id')

虽然您找到的Order.includes(:user).merge(User.unscoped)解决方案看起来更好一点,除非您真的只想要一个查询

答案 2 :(得分:0)

您可以在同一模型上定义另一个关联,以专门定位那些已删除的用户:

此示例的工作原理假设您使用act-as-paranoid来处理软删除。

class Order 
  belongs_to :user
  belongs_to :all_user, -> { with_deleted }, foreign_key: 'user_id'
end

然后选择你的武器:

Order.includes(:user).pluck(:email)     # Only non soft-deleted emails
Order.includes(:all_user).pluck(:email) # All emails including where deleted_at is null

```