Наследование одной таблицы - имя дополнительного класса - PullRequest
0 голосов
/ 22 февраля 2019

У меня есть ситуация в моем приложении на 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 здесь?Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 03 марта 2019

После подробного изучения и углубления в исходный код Rails STI я обнаружил, что мой сценарий должен будет переопределить стандартную STI Rails.Вот что мне нужно для достижения цели:


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.

0 голосов
/ 22 февраля 2019

Вы можете запросить так:

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