重新定义Rails的方法

dcw*_*dcw 16 ruby ruby-on-rails

Rails方法Array#to_sentence允许以下内容:

['a', 'b', 'c'].to_sentence # gives: "a, b, and c"
Run Code Online (Sandbox Code Playgroud)

我想扩展这个方法以允许它占用一个块,这样你就可以做类似下面的事情(其中人是Person对象的数组,它具有name属性):

people.to_sentence { |person| person.name }
# => "Bill, John, and Mark"
Run Code Online (Sandbox Code Playgroud)

编写扩展方法时没有问题.但我无法确定在哪里放置它.Rails核心扩展在某个深处加载ActiveSupport.我需要一个总是加载用户定义代码的地方,并预先加载(在任何应用程序代码之前).

pts*_*pts 23

创造config/initializers/super_to_sentence.rb.加载Rails后,将加载此目录中的所有文件,因此您将有机会覆盖Rails的定义Array#to_sentence.

对于要在加载Rails之前加载的代码,将其添加到config/environment.rb.


Aug*_*aas 14

我喜欢这样做:

# config/initializers/app.rb
Dir[File.join(Rails.root, "lib", "core_ext", "*.rb")].each {|l| require l }

# lib/core_ext/array.rb
class Array
  def to_sentence_with_block(*args, &block)
    if block_given?
      # do something...
      # to_sentence_without_block(*args) perhaps?
    else
      to_sentence_without_block(*args)
    end
  end
  alias_method_chain :to_sentence, :block
end
Run Code Online (Sandbox Code Playgroud)


nas*_*orn 14

我认为这是一个丑陋的想法.你为什么不写

people.collect { |person| person.name }.to_sentence
Run Code Online (Sandbox Code Playgroud)

这看起来几乎一样,不会混淆其他阅读代码的人(比如2年内你自己)

  • 到现在为止,它变得更短:`people.map(&:name).to_sentence` (2认同)