2016-12-01 32 views
3

我有两个型号:如何在join/eager_load中查找default_scope?

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 

如何使导轨在加入unscope关联?

回答

1

你可以试试这个。它适用于Rails 3,但不知道Rails 4.

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

它仍然有效:http://api.rubyonrails.org/classes/ActiveRecord/Scoping/Default/ClassMethods.html #method-i-unscoped – lcguida

+0

谢谢。但是,如果我有多重关系来取景,我不得不多次包装它。我想知道这是否可以用其他方式完成? – Anton

0

我通过手动编写连接查询来解决此问题。对于你的情况应该是这样的:

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

虽然Order.includes(:user).merge(User.unscoped)解决方案,你发现了,看起来有点更好,除非你真的想只有一个查询

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 

```