Simple & Short
В зависимости от возможности повторного использования вы можете выбрать различные варианты.Короткий вариант - просто определить методы, используя цикл в комбинации с #define_method
.
class SomeModel < ApplicationRecord
option_accessors = ['key1', 'key2']
option_accessors.map(&:to_s).each do |accessor_name|
# ^ in case you provide symbols in option_accessors
# this can be left out if know this is not the case
define_method accessor_name do
options.dig('details', accessor_name)
end
define_method "#{accessor_name}=" do |value|
details = options['details'] ||= {}
details[accessor_name] ||= 0
details[accessor_name] += value
end
end
end
Написание модуля
В качестве альтернативы вы можете написать модуль, которыйпредоставить вышеперечисленное в качестве помощников.Простой модуль может выглядеть примерно так:
# app/model_helpers/option_details_attribute_accessors.rb
module OptionDetailsAttributeAccessors
def option_details_attr_reader(*accessors)
accessors.map(&:to_s).each do |accessor|
define_method accessor do
options.dig('details', accessor)
end
end
end
def option_details_attr_writer(*accessors)
accessors.map(&:to_s).each do |accessor|
define_method "#{accessor}=" do |value|
details = options['details'] ||= {}
details[accessor] ||= 0
details[accessor] += value
end
end
end
def option_details_attr_accessor(*accessors)
option_details_attr_reader(*accessors)
option_details_attr_writer(*accessors)
end
end
Теперь вы можете просто расширить свой класс с помощью этих помощников и легко добавлять читателей / писателей.
class SomeModel < ApplicationRecord
extend OptionDetailsAttributeAccessors
option_details_attr_accessor :key1, :key2
end
Если что-то неясно, просто спроситепрочь в комментариях.