Как расширить класс Object в Rails? - PullRequest
6 голосов
/ 01 мая 2011

Я хотел бы добавить метод 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 }

Отлично работает в простом скрипте на Ruby

p nil.nil_or_empty? #=> true
p ''.nil_or_empty? #=> true
p [].nil_or_empty? #=> true
p 0.nil_or_empty? #=> false

Однако, когда я добавляю его в мой библиотечный файл lib/extensions.rb в приложении Rails 3, кажется, что он не добавлен

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

Я загружаю файл библиотеки (все остальные расширения из этого файла работают нормально) и

# config/application.rb
# ...
config.autoload_paths << './lib'

Где я не прав?

Ответы [ 2 ]

16 голосов
/ 01 мая 2011

Во-первых, проще открыть класс Object напрямую:

class Object
  def nil_or_empty?
    nil? || respond_to?(:empty?) && empty?
    # or even shorter: nil? || try(:empty?)
  end
end

Во-вторых, указание Rails на автозагрузку / lib не означает, что файлы в / lib будут загружены при запуске вашего приложения - это означает, что когда вы используете константу, которая в данный момент не определена, Rails будет искать файл в / lib соответствует этой константе. Например, если вы ссылались на ObjectExtensions в коде приложения Rails, и он где-то еще не был определен, Rails ожидает найти его в lib / object_extensions.rb.

Поскольку вы не можете расширять базовый класс в / lib, как это, лучше поместить базовые расширения в каталог config / initializer. Rails загрузит все файлы там автоматически при загрузке вашего приложения. Поэтому попробуйте поместить указанное выше расширение Object в config / initializers / object_extension.rb или config / initializers / extensions / object.rb, или что-то подобное, и все должно работать нормально.

7 голосов
/ 01 мая 2011

В этом конкретном случае вы можете просто использовать предоставляемый Rails Object#blank?.Для обратного есть Object#present?.

#blank?, как ваш метод, но также рассматривает пустые строки, например " ", как пустые.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...