简体   繁体   English

覆盖Rails核心mixin方法,并且仍然能够调用旧方法

[英]Overring a Rails core mixin method, and still being able to call the old method

Ok title is confusing, Ill tell you my problem first: 好的标题令人困惑,我先告诉你我的问题:

the polymorphic_url method was changed in Rails 2.2.1 to include some extra functionality I need. 在Rails 2.2.1中更改了polymorphic_url方法,以包括我需要的一些额外功能。 However, I want to make the application still work in older versions of Rails, so I wanted to patch on the 2.2.1 behaviour if an older Rails version is running. 但是,我想使该应用程序在旧版本的Rails中仍然可以工作,因此如果要运行旧版本的Rails,我想对2.2.1行为进行修补。

alias_method_chain to the rescue right? alias_method_chain救援了吗? I cant get it to work. 我无法正常工作。

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

Now I first tried putting this in the helper - alias_method_chain fails because polymorphic_url isnt defined by then. 现在,我首先尝试将其放在辅助程序中alias_method_chain失败,因为那时尚未定义polymorphic_url So I moved the same code into the controller, and it doesnt error, but it gets ignored. 所以我将相同的代码移入控制器,它没有错误,但是被忽略了。 Then I tried patching it into ApplicationController::Base with a plugin - polymorphic_url is still not defined. 然后,我尝试使用插件将其修补到ApplicationController :: Base中-仍然未定义polymorphic_url

polymorphic_url is defined in the module ActionController::PolymorphicRoutes. polymorphic_url在模块ActionController :: PolymorphicRoutes中定义。 I dont really know when/where it is mixed into the controller/view. 我真的不知道何时/何地将其混入控制器/视图中。

How can I wrap this method in the way i want to? 如何以我想要的方式包装此方法?

Before we proceed, are you sure that polymorphic_url existed in Rails version prior to 2.2.1? 在我们继续之前,您确定2.2.1之前的Rails版本中存在polymorphic_url吗?

You're code is mostly right, you're forgetting to call the original version of the method. 您的代码基本上是正确的,而您忘记了调用该方法的原始版本。 Which is renamed polymorphic_url_without_compat after the alias_method_chain call. 在alias_method_chain调用之后,将其重命名为polymorphic_url_without_compat。

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

You mentioned you tried to add it to a plugin, so the following may not be necessary if the previous bit fixed your problem. 您提到您尝试将其添加到插件中,因此,如果前一点解决了您的问题,则可能不需要执行以下操作。

The best way to ensure it's loaded after the rails core, is to turn it into a plugin. 确保将其加载到rails核心之后的最佳方法是将其变成插件。

$ script/generate plugin polymorphic_url_backport

Will create a plugin stub. 将创建一个插件存根。 All directions from this point on are relevant to the created plugin directory. 此后的所有指示都与创建的插件目录相关。

In the init.rb add 在init.rb中添加

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

Then paste the above code into your lib/yournamespace.rb 然后将上面的代码粘贴到您的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  

Just make sure the plugin ships with your application and there should be no problems. 只要确保插件与您的应用程序一起提供,就不会有问题。 You could alternately add this to the lib of your rails root, but I'm no sure exactly where you would place the require code to run it at the right time. 您可以将其替换添加到rails根目录的lib中,但是我不确定您将在正确的时间放置要求代码的确切位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM