如何在Rails中扩展类Object?

And*_*rei 6 ruby ruby-on-rails object

我想nil_or_empty?为所有类添加方法,因此我定义

module ObjectExtensions
  def nil_or_empty?
    return self.nil? || (self.respond_to?('empty?') && self.empty?)
  end
end
::Object.class_eval { include ::ObjectExtensions }
Run Code Online (Sandbox Code Playgroud)

它在一个简单的Ruby脚本中工作正常

p nil.nil_or_empty? #=> true
p ''.nil_or_empty? #=> true
p [].nil_or_empty? #=> true
p 0.nil_or_empty? #=> false
Run Code Online (Sandbox Code Playgroud)

但是,当我lib/extensions.rb在Rails 3应用程序中将其添加到我的库文件时,似乎没有添加

NoMethodError (undefined method `nil_or_empty?' for nil:NilClass):
  app/controllers/application_controller.rb:111:in `before_filter_test'
Run Code Online (Sandbox Code Playgroud)

我加载库文件(该文件中的所有其他扩展都正常工作)和

# config/application.rb
# ...
config.autoload_paths << './lib'
Run Code Online (Sandbox Code Playgroud)

我哪里错了?

Pre*_*ids 16

首先,直接重新打开Object类更简洁:

class Object
  def nil_or_empty?
    nil? || respond_to?(:empty?) && empty?
    # or even shorter: nil? || try(:empty?)
  end
end
Run Code Online (Sandbox Code Playgroud)

第二,告诉Rails的自动加载/ lib目录并不意味着在/ lib中的文件被加载,当你的应用程序启动 - 这意味着,当您使用的不是当前定义的常量,Rails会寻找在/ lib下相应文件到那个常数.例如,如果你提到ObjectExtensions在您的Rails应用程序的代码,它是不是已经定义的地方,Rails的希望找到它的lib/object_extensions.rb.

由于您不能像这样在/ lib中扩展核心类,因此最好将核心扩展放在config/initializers目录中.当您的应用程序启动时,Rails会自动加载其中的所有文件.所以尝试将上面的Object扩展放在config/initializers/object_extension.rb或config/initializers/extensions/object.rb或类似的东西中,一切都应该正常工作.


Hen*_*k N 7

在这种特殊情况下,您可以使用提供的Rails Object#blank?.反之,有Object#present?.

#blank?就像你的方法一样,但也认为所有的空白字符串"   "都是空白的.