Переопределяя у 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, а потом его рейзануть обратно если не выполнилось необходимое условие.
def method_missing(name, *args)
super
rescue NoMethodError
preferences[name] || raise
end

Не знал, что в activerecord так набыдлокодили. Интересно, а что мешает просто тупо залезть в базу, посмотреть на все атрибуты и для каждого сделать define_method вместо того, чтобы портить method_missing?
единственное объяснение, что я придумал – отложенная инициализация, чтобы неиспользуемые атрибуты до поры-до времени не ели память зазря. Но оно мне кажется маловероятным.
В проекте я, скорее всего, буду генерить методы доступа к данным, потому как у меня в базе всего одно поле preferences, в которое сериализуются все “атрибуты”, которые, в свою очередь, известны только на момент рантайма и берутся из конфигурационных файлов и могут быть любыми.
Тут я хотел показать идею.