单表继承 - 附加类名

问题描述 投票:1回答:2

我在我的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条款吗?提前致谢。

ruby-on-rails ruby-on-rails-4 activerecord single-table-inheritance sti
2个回答
0
投票

您可以这样查询:

Candidate.where(
  Candidate.inheritance_column => [Candidate::Site, Site, SomeOtherClass].map(&:sti_name)
).count

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

© www.soinside.com 2019 - 2024. All rights reserved.