在执行ActiveRecord default_scope
时尝试跳过join
时遇到一些问题。
即使代码库很大,我也只是展示基础知识,因为我认为它很好地说明了问题所在:
class Client
belongs_to :company
end
class Company
default_scope { where(version_id: nil) }
end
我正在构建一个复杂的报表,因此我需要连接多个表并对其进行过滤。但是,在获取Client
时,我无法成功跳过默认范围。
Client.joins(:company).to_sql
# SELECT clients.* FROM clients INNER JOIN companies
# ON companies.id = clients.company_id AND companies.version_id IS NULL
如您所见,它会自动包含Company
default_scope
。所以我尝试了这个:
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
同样,即使将unscoped
与该块一起使用,我也得到相同的结果。
然后,我决定使用unscoped
范围向模型添加新的关联:
class Client
belongs_to :company
belongs_to :unscoped_company, -> { unscoped }, foreign_key: :company_id, class_name: "Company"
end
添加了这一点,我再次尝试:
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
仍然应用了作用域。
您知道如何在不应用default_scope
的情况下成功地联接两个表吗?
不能删除default_scope
,因为这是一个很大的应用程序,因此更改将需要太多时间。
Rails v4.2.7
Ruby v2.2.3
答案 0 :(得分:1)
似乎没有您想要的简单解决方案。有几个讨论线程可供参考。
https://github.com/rails/rails/issues/20679
https://github.com/rails/rails/issues/20011
但是我喜欢@iGian的建议。
答案 1 :(得分:0)
您可以手动执行:
i
答案 2 :(得分:0)
直接作为类方法应用
Client.unscoped.joins(:company).to_sql
答案 3 :(得分:0)
我做了一些研究,却没有找到直接的解决方案。
这里有两个解决方法。我不能说他们是否将在您的链式联接中工作。
Client.joins("INNER JOINS companies ON companies.id = clients.company_id).to_sql
CompanyUnscoped
类,该类继承自Company
,并删除了default_scope:
class CompanyUnscoped < Company
self.default_scopes = []
end
别忘了将此行添加到Client类:
belongs_to :company_unscoped, foreign_key: :company_id
那你应该可以打电话
Client.joins(:company_unscoped)
#=> SELECT "clients".* FROM "clients" INNER JOIN "companies" ON "companies"."id" = "clients"."company_id"
答案 4 :(得分:0)