Можно ли использовать ActiveModel::Type.register
, чтобы можно было передавать аргументы?
Чтобы продемонстрировать, можно ли это повернуть:
class Action < ApplicationRecord
attribute :type, Types::VirtualStringType.new(suffix: 'Action')
end
во что-то вроде
class Action < ApplicationRecord
attribute :type, :virtual_string, suffix: 'Action'
end
@max Я знаю об этом, и было намеренно называть все нисходящие классы после базового, сохраняя версию без суффикса в базе данных.
Звучит слишком сложно и умно.
Вы можете зарегистрировать новый тип, создав config/initializers/active_record_types.rb
Rails.application.config.to_prepare do
ActiveRecord::Type.register(:virtual_string, Types::VirtualStringType)
end
Класс типа должен будет принять параметры/аргументы в initialize
следующим образом:
def initialize(**args)
@suffix = args[:suffix].to_s
end
Вот пример реализации:
module Types
class VirtualStringType < ActiveRecord::Type::String
def initialize(**args)
@suffix = args[:suffix].to_s
end
def cast_value(value)
value.to_s + @suffix unless value.nil?
end
def serialize(value)
value.chomp(@suffix) unless value.nil?
end
def changed_in_place?(original_value_for_database, value)
original_value_for_database != serialize(value)
end
end
end
Вы должны знать, что
type
— это столбец вывода типа по умолчанию для наследования одной таблицы в ActiveRecord. Хотя я не уверен, что наличие несохраняемого атрибута с таким именем приведет к тому, что Rails попытается загрузить неправильные настройки классаself.inheritance_column = nil
, было бы разумной предосторожностью. api.rubyonrails.org/classes/ActiveRecord/Inheritance.html