Переопределяя у ActiveRecord модели #method_missing важно помнить, что методы чтения атрибутов генерятся через сам #method_missing
Так, например, код
class Appearance < ActiveRecord::Base
serialize :prefereneces, HashWithIndifferentAccess
def method_missing(name, *args)
preferences[name] || super
end
end
вывалит Exception SystemStackError: stack level too deep
Обойти это можно, вызвав сначала super и перехватив NoMethodError, а потом его рейзануть обратно [...]
Метод ActiveRecord::Base#update_attribute согласно документации предназначен для обновления отдельного атрибута и … дальше мало кто читает внимательно — сохранения без прохождения процесса валидации, что приводит к некоторым побочным эффектам (side effects), когда метод может обновлять любое кол-во атрибутов и даже сохранять ассоциации! Смотрите.
Создаем тестовый проект
$ rails side_effects_in_rails_1_active_record_update_attribute
$ cd side_effects_in_rails_1_active_record_update_attribute
$ script/generate rspec_model Post title:string body:string
$ rake db:migrate
$ [...]
Не первый раз натыкаюсь в коде на округление до 3-го знака после запятой таким способом
require ‘active_support’
# …
(object.to_f*1000).round/1000.0
Я не даром отметил require ‘active_support’, если бы этого не было выше по коду — этой заметки не было бы.
Дело в том, что ActiveSupport расширяет метод Float#round, добавляя в него дополнительный аргумент precision, и в случае если он задан, [...]
Ничего не предвещало беды
В текущем проекте у нас используется довольно полезный плагин what_column,
который после каждой миграции обновляет файлы в app/models, добавляя в коментарии
название атрибутов и типы полей. Примерно вот так:
class Post < ActiveRecord::Base
# === List of columns ===
# id : [...]