【问题标题】:How to unscope default_scope in join/eager_load?如何在 join/eager_load 中取消 default_scope 的范围?
【发布时间】:2016-12-01 12:18:24
【问题描述】:

我有两个模型:

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 "users"."deleted_at" IS NULL" 添加到 join 语句中。

如果我指定关联范围,则不会发生任何变化:

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

如何在连接中取消关联范围?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    你可以这样试试。它适用于 Rails >= 3

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

    【讨论】:

    【解决方案2】:

    我通过手动编写连接查询解决了这个问题。对于您的情况,它应该如下所示:

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

    尽管您找到的 Order.includes(:user).merge(User.unscoped)solution 看起来更好一些,除非您真的只想有一个查询

    【讨论】:

      【解决方案3】:

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

      假设您使用 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
      

      ```

      【讨论】:

        猜你喜欢
        • 2019-10-02
        • 2014-09-16
        • 1970-01-01
        • 2014-04-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多