I am having some issues when trying to skip a default_scope
when doing an ActiveRecord join
.
Even though the codebase is quite large, I am just showing the basics as I think it shows pretty well what the problem is:
class Client
belongs_to :company
end
class Company
default_scope { where(version_id: nil) }
end
I am building a complex report, so I need to join multiple tables and filter on them. However, I can't successfully skip the default scope when fetching Client
s.
Client.joins(:company).to_sql
# SELECT clients.* FROM clients INNER JOIN companies
# ON companies.id = clients.company_id AND companies.version_id IS NULL
As you can see that is automatically including the Company
default_scope
. So I tried this:
Company.unscoped { Client.joins(:company) }.to_sql
# SELECT clients.* FROM clients INNER JOIN companies
# ON companies.id = clients.company_id AND companies.version_id IS NULL
Again, I got the same result, even when using unscoped
with the block.
Then I decided to add a new association to the model, with the unscoped
scope:
class Client
belongs_to :company
belongs_to :unscoped_company, -> { unscoped }, foreign_key: :company_id, class_name: "Company"
end
Having added that, I gave another try:
Client.joins(:unscoped_company).to_sql
# SELECT clients.* FROM clients INNER JOIN companies
# ON companies.id = clients.company_id AND companies.version_id IS NULL
And still the scoped is being applied.
Do you know how can I successfully join both tables without applying that default_scope
?
Removing that default_scope
is not an option as It is a big application and changing that will require too much time.
Rails v4.2.7
Ruby v2.2.3
I did some research without finding any straight solution.
Here a couple of workarounds. I cannot say if they're going to work in your chained joins.
Client.joins("INNER JOINS companies ON companies.id = clients.company_id").to_sql
class CompanyUnscoped < Company
self.default_scopes = []
end
Don't forget to add this line to Client class:
belongs_to :company_unscoped, foreign_key: :company_id
Then you should be able to call
Client.joins(:company_unscoped)
#=> SELECT "clients".* FROM "clients" INNER JOIN "companies" ON "companies"."id" = "clients"."company_id"