Я использую Ruby on Rails 3.2.2, и я хотел бы знать, является ли следующий «правильный» / «правильный» / «верный» способ переопределить метод установки для атрибута моего класса.
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self[:attribute_name] = value
end
Код выше, кажется, работает как ожидалось. Однако я хотел бы знать, будут ли в будущем при использовании приведенного выше кода возникать проблемы или, по крайней мере, какие проблемы «следует ожидать» / «могут возникнуть» с Ruby on Rails . Если это неправильный способ переопределить метод установки, каков правильный путь?
Примечание : если я использую код
attr_accessible :attribute_name
def attribute_name=(value)
... # Some custom operation.
self.attribute_name = value
end
Я получаю следующую ошибку:
SystemStackError (stack level too deep):
actionpack (3.2.2) lib/action_dispatch/middleware/reloader.rb:70
Ответы:
================================================== ========================= Обновление: 19 июля 2017 г.
Теперь документация по Rails также предлагает использовать
super
вот так:================================================== =========================
Оригинальный ответ
Если вы хотите переопределить методы установки для столбцов таблицы при доступе через модели, это способ сделать это.
Смотрите раздел Переопределение методов доступа по умолчанию в документации по Rails.
Итак, ваш первый метод - это правильный способ переопределить установщики столбцов в моделях Ruby on Rails. Эти средства доступа уже предоставлены Rails для доступа к столбцам таблицы в качестве атрибутов модели. Это то, что мы называем ActiveRecord ORM.
Также имейте в виду, что
attr_accessible
верхняя часть модели не имеет ничего общего с аксессуарами. Он имеет совершенно другую функциональность (см. Этот вопрос )Но в чистом Ruby, если вы определили методы доступа для класса и хотите переопределить метод установки, вы должны использовать переменную экземпляра следующим образом:
Это будет легче понять, если вы знаете, что
attr_accessor
делает. Кодattr_accessor :name
эквивалентен этим двум методам (getter и setter)Также ваш второй метод дает сбой, потому что он вызовет бесконечный цикл, так как вы вызываете тот же метод
attribute_name=
внутри этого метода.источник
attr_accessible
так как его там больше нет, и он должен работатьsuper
?super
могут не работать. Но, похоже, дело не в этом. Я только что проверил, и это работает для меня. Также этот вопрос задают так жеwrite_attribute
. Конверсии будут пропущены. Имейте в виду, чтоwrite_attribute
конверсии часовых поясов с датами будут пропущены, что почти всегда будет нежелательным.Используйте
super
ключевое слово:И наоборот, чтобы переопределить читателя:
источник
В рельсах 4
скажем, у вас есть возрастной атрибут в вашей таблице
Примечание: для новичков в рельсах 4 вам не нужно указывать attr_accessible в модели. Вместо этого вы должны занести в белый список свои атрибуты на уровне контроллера, используя метод разрешения .
источник
Я обнаружил, что (по крайней мере для коллекций отношений ActiveRecord) работает следующий шаблон:
(Это захватывает первые 3 не повторяющихся записи в переданном массиве.)
источник
Использование
attr_writer
для перезаписи установщика attr_writer: имя_атрибутаисточник