2016-02-05 54 views
1

我试图定义Rails'parameterize的一个版本,它不会导致生成的字符串不合适。在Rails中,如何以及在哪里定义一个稍微改变现有Rails方法的新方法

# File activesupport/lib/active_support/inflector/transliterate.rb, line 80 
def parameterize(string, sep = '-') 
    # replace accented chars with their ascii equivalents 
    parameterized_string = transliterate(string) 
    # Turn unwanted chars into the separator 
    parameterized_string.gsub!(/[^a-z0-9\-_]+/, sep) 
    unless sep.nil? || sep.empty? 
    re_sep = Regexp.escape(sep) 
    # No more than one of the separator in a row. 
    parameterized_string.gsub!(/#{re_sep}{2,}/, sep) 
    # Remove leading/trailing separator. 
    parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/, '') 
    end 
    parameterized_string.downcase 
end 

我会想我会做到这一点:

# /lib/inflector.rb 
module Inflector 
    module ParameterizeCs 
    # Parameterize a string without making it lowercase 
    # by editing Rails' parameterize 
    def parameterize_cs(string, sep = '-') 
     .... 
    end 
    end 
end 

# Actually monkey-patch Inflector 
Inflector.include Inflector::ParameterizeCs 

但我发现了这个错误:undefined method parameterize_cs

任何想法?

+0

是不是你** **结束**你的**模块Para​​meterizeCs **? – Lymuel

回答

0

您是否尝试过,比如增加一类,所以你可以调用parameterize_cs方法:

# /lib/inflector.rb 
module Inflector 
    class ParameterizeCs 
    # Parameterize a string without making it lowercase 
    # by editing Rails' parameterize 
    def parameterize_cs(string, sep = '-') 
     .... 
    end 
    end 
end 

# Actually monkey-patch Inflector 
Inflector.include Inflector::ParameterizeCs 
0

好了,先确保你已经配置你的config/application.rb中文件加载的文件/ lib文件夹:

config.autoload_paths += %W(#{config.root}/lib) 

这会自动加载您的新文件。但是,根据您的设置,它不会进入ActiveSupport::Inflector,而是进入您定义的普通Inflector模块。

如果您想在ActiveSupport :: Inflector中定义该方法,则必须指定完整路径,之后您应该可以简单地调用该方法。顺便说一句,如果你只有这种单一的方法,module ParameterizeCs似乎对我来说是不必要的,所以我在这里跳过它。

module ActiveSupport 
    module Inflector 
     # Parameterize a string without making it lowercase 
     # by editing Rails' parameterize 
     def parameterize_cs(string, sep = '-') 
      .... 
     end 
    end 
end 

编辑:

请张贴在那里你尝试include模块的代码,并调用parameterize_cs。否则,很难确定可能会出现什么问题。但我会根据我的猜测提供更多信息。

如果您已加载文件,则该方法已存在。不需要include它就是这样。您可以通过调用ActiveSupport::Inflector.instance_methods来检查它,它将列出ActiveSupport::Inflector中的所有实例方法。你应该可以在那里看到:parameterize_cs

另一件要检查的事情是,如果您试图从模块本身调用parameterize_cs,如ActiveSupport::Inflector.parameterize_cs。该方法被定义为一个实例方法,因此它只能从您称为include ActiveSupport::Inflector的类的实例中调用。下面的代码将ActiveSupport :: Inflector模块包含为String(以确保parameterize_cs已加载到String中),然后从String的实例中调用parameterize_cs

String.include ActiveSupport::Inflector 
s = "foobar" 
s.parameterize_cs("bar") 

如果要直接从模块调用parameterize_csActiveSupport::Inflector.parameterize_cs,则声明该方法作为一类方法(即def self.parameterize_cs)。

+0

我这样做,似乎在/ lib加载文件,但该功能仍然不可用。这一行应该是什么:'ActiveSupport.include ActiveSupport :: Inflector'。这是我得到的错误:'NoMethodError(undefined method parameter_cs for#): app/models/user。rb:56:in normalize_friendly_id config/initializers/friendly_id_finder.rb:10:in set_slug app/controllers/registrations_controller.rb:27:in update_resource' – Catalin

+0

我编辑了我的答案。如果它仍然没有工作。请张贴更多你的代码。 – Harfangk

+0

这可能会起作用,但在那之前我有一个不同的问题,可能会简化我的情况。看起来像新版本的rails这是可能的:'“John Smith”.parameterize(preserve_case:true)#=>“John-Smith”(http://edgeguides.rubyonrails.org/active_support_core_extensions.html),但是当我试图在轨道上的轨道控制台4.2.0我得到这个错误'TypeError:没有隐式转换哈希到字符串'。有任何想法吗 ?我还将复习并试用您提出的解决方案 – Catalin