单一 Table 继承 - 附加 Class 名称
Single Table Inheritance - Additional Class Name
我的 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
子句吗?提前致谢。
您可以这样查询:
Candidate.where(
Candidate.inheritance_column => [Candidate::Site, Site, SomeOtherClass].map(&:sti_name)
).count
在详细研究并深入研究 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
.
我的 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
子句吗?提前致谢。
您可以这样查询:
Candidate.where(
Candidate.inheritance_column => [Candidate::Site, Site, SomeOtherClass].map(&:sti_name)
).count
在详细研究并深入研究 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
.