Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unscope default_scope in join/eager_load?

I have two models:

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

class Order 
  belongs_to :user
end

And I want to get orders with deleted or not deleted users:

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

None of these work.

Every query adds "AND "users"."deleted_at" IS NULL" into join statement.

Nothing changes if I specify association scope:

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

However includes works as expected:

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

How can I make rails to unscope association in a join?

like image 629
Anton Avatar asked Dec 01 '16 12:12

Anton


1 Answers

I solved this issue by writing join query manually. For your case it should look like:

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

Although Order.includes(:user).merge(User.unscoped)solution, that you found, looks a bit nicer, unless you really want to have only one query

like image 129
divideByZero Avatar answered Oct 18 '22 17:10

divideByZero