2016-12-01 22 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 

```