Rails方法Array#to_sentence
允许以下内容:
['a', 'b', 'c'].to_sentence # gives: "a, b, and c"
我想扩展此方法以允许它占用一个块,以便您可以执行以下操作(其中people是Person对象的数组,具有name属性):
people.to_sentence { |person| person.name }
# => "Bill, John, and Mark"
编写扩展方法时没有问题。但我无法确定在哪里放置它。 Rails核心扩展在ActiveSupport
的深处向下加载。
我需要一个总是加载用户定义代码的地方,并预先加载(在任何应用程序代码之前)。
答案 0 :(得分:23)
创建config/initializers/super_to_sentence.rb
。加载Rails后,将加载此目录中的所有文件,因此您将有机会覆盖Rails对Array#to_sentence
的定义。
对于要在加载Rails之前加载的代码,请将其添加到config/environment.rb
。
答案 1 :(得分: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
答案 2 :(得分:14)
我认为这是一个丑陋的想法。你为什么不写
people.collect { |person| person.name }.to_sentence
这看起来几乎相同,不会混淆其他阅读代码的人(比如2年内你自己)
答案 3 :(得分:1)
只是在网上搜索,似乎很好的做法是在lib /
中添加它所以,如果你想扩展一些ruby类(在我的例子中,DateTime),只需将代码放在.rb中,然后放在config / environment.rb中:
config.after_initialize do
require "lib/super_datetime.rb"
end
我的super_datetime.rb看起来像这样(来自http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/140184的代码):
class DateTime
def days_in_month
self::class.civil(year, month, -1).day
end
alias dim days_in_month
def weekdays
(1..dim).to_a
end
end
重新启动服务器,您将可以访问所有DateTime对象的新方法。