Переопределение базового метода mixin в Rails и возможность вызова старого метода - PullRequest
1 голос
/ 25 октября 2009

Хорошо, название озадачивает, сначала я расскажу о своей проблеме:

метод polymorphic_url был изменен в Rails 2.2.1 для включения некоторых дополнительных функций, которые мне нужны. Однако я хочу, чтобы приложение все еще работало в старых версиях Rails, поэтому я хотел установить патч на поведение 2.2.1, если запущена более старая версия Rails.

alias_method_chain на помощь, верно? Я не могу заставить его работать.

def polymorphic_url_with_compat(*args)
  whatever...
  return polymorphic_url(*args)
end
alias_method_chain :polymorphic_url, :compat

Теперь я сначала попытался поместить это в помощник - alias_method_chain не удается, потому что polymorphic_url не определено к тому времени. Таким образом, я переместил тот же код в контроллер, и это не ошибка, но он игнорируется. Затем я попытался исправить это в ApplicationController :: Base с помощью плагина - polymorphic_url все еще не определено.

polymorphic_url определяется в модуле ActionController :: PolymorphicRoutes. Я действительно не знаю, когда / где это смешано с контроллером / представлением.

Как мне обернуть этот метод так, как я хочу?

1 Ответ

3 голосов
/ 25 октября 2009

Прежде чем мы продолжим, вы уверены, что polymorphic_url существовал в версии Rails до 2.2.1?

Ваш код в основном правильный, вы забыли вызвать исходную версию метода. Который переименован в polymorphic_url_without_compat после вызова alias_method_chain.

class ActiveRecord::PolymorphicRoutes
  def polymorphic_url_with_compat(*args)
    whatever...
    return polymorphic_url_without_compat(*args)
  end
  alias_method_chain :polymorphic_url, :compat
end

Вы упомянули, что пытались добавить его в плагин, поэтому следующее может не понадобиться, если предыдущий бит исправил вашу проблему.

Лучший способ убедиться, что он загружен после ядра рельсов, - превратить его в плагин.

$ script/generate plugin polymorphic_url_backport

Создает заглушку плагина. Все указания с этого момента относятся к созданному каталогу плагинов.

В init.rb добавить

if RAILS_GEM_VERSION < "2.2.1"
  require File.dirname(__FILE__) + '/lib/yournamespace'
  ActionController::PolymorphicRoutes.send(:include, YourNameSpace::ActionController::PolymorphicRoutes) 
end

Затем вставьте приведенный выше код в ваш lib / yournamespace.rb

module YourNameSpace
  class ActiveRecord::PolymorphicRoutes
    def included(base)
      base.class_eval %~
        def polymorphic_url_with_compat(*args)
          whatever...
          return polymorphic_url_without_compat(*args)
        end
        alias_method_chain :polymorphic_url, :compat
      ~
    end
  end
end  

Просто убедитесь, что плагин поставляется с вашим приложением, и проблем не должно быть. Вы можете поочередно добавить это в библиотеку своего корневого каталога rails, но я не уверен, где именно вы разместите код, необходимый для его запуска в нужное время.

...