У меня есть простой модуль стиля activ_as, который включен в ActiveRecord :: Base.Назначение этого модуля:
добавить ассоциацию has_one к модели ActiveRecord
добавить отсутствующий метод в экземпляры, который будет направлятьлюбые отсутствующие методы для связанного экземпляра.
Вот пример модуля:
module TestModule
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def test_me_out
has_one :text_page
send(:include, InstanceMethods)
end
end
module InstanceMethods
def method_missing(method, *args, &block)
Rails.logger.debug "#{method}"
#text_page.send(method, *args, &block)
text_page
end
end
end
И то, как я мог бы использовать его в модели AR ...
Class Page < ActiveRecord::Base
test_me_out
end
Проблема в том, что если метод * method_missing * в модуле запущен, он немедленно вызывает ошибку "слишком большой уровень стека" внутри method_missing ....
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
app/lib/test_module.rb:24:in `method_missing'
...
Метод, который отсутствует, это 'id'?!?Вы заметите, что я закомментировал пример строки кода, которая отправляет отсутствующий метод в связанный класс - text_page.send (метод, * args, & block), поскольку достаточно вызвать ассоциацию - text_page - для запускаслишком глубокая ошибка на уровне стека.
Кто-нибудь может определить ошибку?
PS.Конечно, это приведенный пример действительного модуля и варианта использования, однако это иллюстрирует ошибку и чудесно дает сбой.
SOLUTION
Большое спасибоАлекс для спасения.Идентификатор ActiveRecord генерируется динамически с использованием метода отсутствующего блока.Следующий код работает так, как он позволяет отсутствующему методу: id перейти в super:
def method_missing(method, *args, &block)
if method != :id && text_page.respond_to?(method)
text_page.send(method, *args, &block)
else
super
end
end