我在Rails 4应用程序中遇到一种情况,我有STI,想通过其他type
自定义默认查询。
课程:
class Candidate < ApplicationRecord
end
class Candidate::Site < Candidate
end
现在,如果我进行查询,则会得到如下结果:
> Candidate::Site.count
# SELECT COUNT(*) FROM "candidates" WHERE "candidates"."type" IN ('Candidate::Site')
=> 0
现在,在我的情况下,我想添加一个额外的type
,该查询应每次查找。通过利用IN
子句,可以触发我的预期查询:
SELECT COUNT(*) FROM "candidates" WHERE "candidates"."type" IN ('Candidate::Site', 'Site')
有人可以帮我控制这里的IN
子句吗?预先感谢。
答案 0 :(得分:0)
您可以这样查询:
Candidate.where(
Candidate.inheritance_column => [Candidate::Site, Site, SomeOtherClass].map(&:sti_name)
).count
答案 1 :(得分:0)
详细研究并深入研究Rails STI源代码后,我发现我的场景将需要覆盖Rails的默认STI。以下是我实现目标所需要的:
class Candidate::Site
# To enable renaming of Site to Candidate::Site
# per ENG-9551, we need to:
# 1. disable the 'type' column from using Rails' built-in STI
self.inheritance_column = :_nonexistant_column_to_bypass_sti
# 2. manually set the type column to Candidate::Site when we save,
# so that new and edited records are saved as Candidate::Site
before_save { self.type = 'Candidate::Site' }
# 3. always report the type as a Candidate::Site
def type
'Candidate::Site'
end
# 4. and set a default scope which only reads type columns that are
# 'Candidate::Site' or 'Site' so that STI
# still appears to be the same as always
default_scope { where(type: 'Candidate::Site').or(where(type: 'Site')) }
...
...
...
end
因此,现在使用Candidate::Site.create
创建的任何新记录都将存储类型Candidate::Site
,而查询将使用默认范围并同时考虑类型Candidate::Site
和Site
。