在Rails中,如何以及在何处定义稍微更改现有Rails方法的新方法

时间:2016-02-05 00:39:29

标签: ruby-on-rails

我正在尝试定义一个版本的Rails'parameterize,它不会对结果字符串进行缩写。

# 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

有什么想法吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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_cs等模块调用ActiveSupport::Inflector.parameterize_cs,请将该方法声明为类方法(即def self.parameterize_cs)。