class Song < ActiveRecord::Base
# Uses an integer of seconds to hold the length of the song
def length=(minutes)
write_attribute(:length, minutes.to_i * 60)
end
def length
read_attribute(:length) / 60
end
end
Это простой пример с помощью rails api doc.
Возможно ли перезаписать все атрибуты для модели без перезаписывания каждого из них?
Я не уверен в случае использования, когда это будет хорошей идеей. Тем не менее, все модели рельсов динамически присваивают свои свойства (предполагая, что они еще не находятся в классе). Ответ частично на ваш вопрос.
Вы можете переопределить методы read_attribute() и write_attribute(). Это применило бы ваши преобразования к каждому атрибуту независимо от того, был ли он написан аксессуаром или заполнен массовым в контроллере. Просто будьте осторожны, чтобы не мутировать важные атрибуты, такие как атрибут id.
Ruby имеет ярлык, который используется в коде rails, который может вам помочь. Это ключевое слово% w. % w создаст массив слов, основанный на символах внутри круглых скобок. Поскольку это массив, вы можете делать такие полезные вещи:
@excludes = %w(id, name)
def read_attribute name
value = super
if(not @excludes.member? name)
value = value.to_i * 60
end
value
end
def write_attribute name, value
if(not @excludes.member? name)
value = value.to_i / 60
end
super
end
Это должно заставить вас начать. Существуют более продвинутые конструкции, такие как использование лямбда и т.д. Имейте в виду, что вы должны написать подробные модульные тесты, чтобы убедиться, что у вас нет непредвиденных последствий. Возможно, вам придется включить больше имен атрибутов в список исключений.
edit: (read | write) _attributes → (read | write) _attribute
Вы ищете что-то подобное? Не знаю, почему вы хотели бы это сделать, но здесь вы идете:)
class Song < ActiveRecord::Base
self.columns_hash.keys.each do |name|
define_method :"#{name}=" do
# set
end
define_method :"#{name}" do
# get
end
# OR
class_eval(<<-METHOD, __FILE__, __LINE__ + 1)
def #{name}=
# set
end
def #{name}
# get
end
METHOD
end
end
content.title
. Мне не очень нравится их подход. По сути, они создают таблицу content_translations, где все переведенные атрибуты являются столбцами, а затем загружают записи перевода, соответствующие I18n.locale. Затем content.title
становится прокси для content.translation(locale).title
. В моем следующем локализованном приложении я пропущу плагин и просто создаю эти таблицы вручную и создаю модель ContentTranslation. Это более понятно, и вы знаете, с каким объектом вы имеете дело.