Невозможно вызвать ассоциацию внутри метода. Помогите! - PullRequest
1 голос
/ 20 января 2011

У меня есть простой модуль стиля activ_as, который включен в ActiveRecord :: Base.Назначение этого модуля:

  1. добавить ассоциацию has_one к модели ActiveRecord

  2. добавить отсутствующий метод в экземпляры, который будет направлятьлюбые отсутствующие методы для связанного экземпляра.

Вот пример модуля:

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

1 Ответ

2 голосов
/ 20 января 2011

Erik - Если я правильно помню, AR использует method_missing для определения атрибутов accessors и т.п. в классе, например они не жестко закодированы. Они хранятся в переменных экземпляра, но методы .id и .id = определяются на лету. В результате я бы рекомендовал определить способ сопоставления отсутствующих методов, которые вы хотите сослаться на связанный интерфейс.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...