2011-05-01 21 views
6

me gustaría añadir método nil_or_empty? a todas las clases, por lo tanto, defino¿Cómo extender la clase Object en Rails?

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

Funciona bien en un simple script de Ruby

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

Sin embargo, cuando lo añado a mi archivo de biblioteca lib/extensions.rb en una aplicación Rails 3, parece que no se añadirán

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

hago cargar el archivo de biblioteca (todos los demás extensio ns de ese archivo funcionan bien) y

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

¿Dónde estoy equivocado?

+0

posible duplicado http://stackoverflow.com/questions/5654517/in-ruby-on-rails-to-extend-the-string-class-where-should-the-code-be-put-in –

Respuesta

16

En primer lugar, es más limpio que acaba de abrir de nuevo la clase de objeto directo:

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

En segundo lugar, contando rieles para carga automática/lib no significa que se cargarán los archivos en/lib cuando su aplicación se pone en marcha - significa que cuando usa una constante que no está definida actualmente, Rails buscará un archivo en/lib correspondiente a esa constante. Por ejemplo, si se refería a ObjectExtensions en su código de aplicación de Rails, y no estaba ya definido en algún lugar, Rails esperaría encontrarlo en lib/object_extensions.rb.

Dado que no se puede extender una clase central en/lib como esta, es una mejor idea colocar extensiones principales en el directorio config/initializers. Rails cargará todos los archivos allí automáticamente cuando se inicie la aplicación. Intente poner la extensión de objeto anterior en config/initializers/object_extension.rb, o config/initializers/extensions/object.rb, o algo similar, y todo debería funcionar bien.

+0

Gracias , ahora lo estoy haciendo de la manera correcta. – Andrei

+0

¡Funcionó para mí! ¡Gracias! –

+0

¿Por qué no puedes extender una clase principal en lib? –

7

En este caso particular, puede utilizar el Object#blank? proporcionado por Rails. Para el inverso, hay Object#present?.

#blank? es como su método, pero también considera que las cadenas totalmente blancas como "   " están en blanco.

+0

Eso es exactamente lo que estaba buscando. ¡Virar! – Andrei

Cuestiones relacionadas