Ruby on rails 单表继承-附加类名

Ruby on rails 单表继承-附加类名,ruby-on-rails,ruby-on-rails-4,activerecord,single-table-inheritance,sti,Ruby On Rails,Ruby On Rails 4,Activerecord,Single Table Inheritance,Sti,我在Rails 4应用程序中遇到了一种情况,我有STI,希望通过额外的类型自定义默认查询 课程: class Candidate < ApplicationRecord end class Candidate::Site < Candidate end 现在,在我的情况下,我想添加一个额外的类型,每次查询都应该查找该类型。通过利用IN子句中的,我希望触发的查询是: SELECT COUNT(*) FROM "candidates" WHERE "candidates"."type

我在Rails 4应用程序中遇到了一种情况,我有STI,希望通过额外的
类型
自定义默认查询

课程:

class Candidate < ApplicationRecord
end

class Candidate::Site < Candidate
end
现在,在我的情况下,我想添加一个额外的
类型
,每次查询都应该查找该类型。通过利用
IN
子句中的
,我希望触发的查询是:

SELECT COUNT(*) FROM "candidates" WHERE "candidates"."type" IN ('Candidate::Site', 'Site')
有人能帮我控制一下这里的
子句中的
吗?提前感谢。

您可以这样查询:

Candidate.where(
  Candidate.inheritance_column => [Candidate::Site, Site, SomeOtherClass].map(&:sti_name)
).count
您可以这样查询:

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

<> P> >现在,用<代码>候选创建的任何新记录:站点.CREATE/<代码>将存储类型<代码>候选::站点< /代码>,查询将使用默认范围,同时考虑类型、<代码>候选::站点< /代码>以及<>代码>站点< /C> >

详细研究和深入到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

<> P> >现在,用<代码>候选创建的任何新记录::站点。创建< /COD>将存储类型<代码>候选::站点< /代码>,而查询将使用默认范围,同时考虑类型、<代码>候选::站点< /代码>以及<代码>站点< /代码>。< /P>实际上,我不能这样做。情况是,我已经让我的应用程序运行在
Candidate::Site
类中。现在,我想将类/模型重命名为
Site
,同时我不想失去对现有表记录的访问权,这些表记录具有
type=Candidate::Site
,没有太多更改。我也想用新类查询现有的。@RAJ是
Site
只是
Candidate::Site
的一个新名称?如果是,那么为什么不更新记录呢?我们正在分阶段进行。还有很多其他的依赖项,所以我们不能马上做。谢谢,事实上,我不能这么做。情况是,我已经让我的应用程序运行在
Candidate::Site
类中。现在,我想将类/模型重命名为
Site
,同时我不想失去对现有表记录的访问权,这些表记录具有
type=Candidate::Site
,没有太多更改。我也想用新类查询现有的。@RAJ是
Site
只是
Candidate::Site
的一个新名称?如果是,那么为什么不更新记录呢?我们正在分阶段进行。还有很多其他的依赖项,所以我们不能马上做。谢谢