asc*_*man 4 ruby activerecord ruby-on-rails
default_scope我在尝试跳过 ActiveRecord 时遇到一些问题join。
尽管代码库相当大,但我只是展示基础知识,因为我认为它很好地说明了问题所在:
class Client
belongs_to :company
end
class Company
default_scope { where(version_id: nil) }
end
Run Code Online (Sandbox Code Playgroud)
我正在构建一个复杂的报告,因此我需要连接多个表并对其进行过滤。但是,在获取 s 时我无法成功跳过默认范围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
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,它会自动包含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
Run Code Online (Sandbox Code Playgroud)
unscoped同样,即使与块一起使用,我也得到了相同的结果。
然后我决定向模型添加一个新的关联,其unscoped范围:
class Client
belongs_to :company
belongs_to :unscoped_company, -> { unscoped }, foreign_key: :company_id, class_name: "Company"
end
Run Code Online (Sandbox Code Playgroud)
添加后,我又尝试了一次:
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
Run Code Online (Sandbox Code Playgroud)
并且仍在应用范围。
您知道如何在不应用它的情况下成功连接两个表吗default_scope?删除它default_scope不是一个选择,因为它是一个大型应用程序,并且更改它需要太多时间。
导轨 v4.2.7
红宝石 v2.2.3
我做了一些研究,但没有找到任何直接的解决方案。
这里有几个解决方法。我不能说它们是否会在您的链接连接中工作。
Client.joins("INNER JOINS companies ON companies.id = clients.company_id").to_sql
Run Code Online (Sandbox Code Playgroud)
class CompanyUnscoped < Company
self.default_scopes = []
end
Run Code Online (Sandbox Code Playgroud)
不要忘记将此行添加到 Client 类中:
belongs_to :company_unscoped, foreign_key: :company_id
Run Code Online (Sandbox Code Playgroud)
然后你应该可以打电话
Client.joins(:company_unscoped)
#=> SELECT "clients".* FROM "clients" INNER JOIN "companies" ON "companies"."id" = "clients"."company_id"
Run Code Online (Sandbox Code Playgroud)