rails modules ruby-on-rails ruby class module

ruby-on-rails - rails where to put modules



Módulos Rails/lib y (5)

Estoy escribiendo un contenedor personalizado para el complemento open_flash_chart . Se coloca en /lib y se carga como un módulo en ApplicationController .

Sin embargo, tengo alguna jerarquía de clases o un pequeño problema.

Desde cualquier controlador, puedo acceder a open_flash_chart funciones de OpenFlashChart como OpenFlashChart , Line , etc.

Sin embargo, en una clase en un módulo /lib , ¡no funciona!

¿Algunas ideas?


En Rails, los módulos 3 / lib no se cargan automáticamente.

Esto es porque la línea:

# config.autoload_paths += %W(#{config.root}/extras)

dentro de config / application.rb se comenta.

Puede intentar descomentar esta línea o, (funcionó incluso mejor para mí), deje esto comentado (para referencia futura) y agregue estas dos líneas:

config.autoload_paths += %W(#{config.root}/lib) config.autoload_paths += Dir["#{config.root}/lib/**/"]


Hay dos formas en que los archivos se cargan en Rails:

  • Se registra en el proceso de autocarga y hace referencia a una constante que corresponde al nombre del archivo. Por ejemplo, si tiene app/controllers/pages_controller.rb y hace referencia a PagesController, la app/controllers/pages_controller.rb cargará automáticamente. Esto sucede para una lista preestablecida de directorios en la ruta de carga. Esta es una característica de Rails, y no es parte del proceso normal de carga de Ruby.
  • Los archivos son explícitamente require d. Si se require un archivo d, Ruby busca en toda la lista de rutas en sus rutas de carga y encuentra el primer caso donde el archivo que require d está en la ruta de carga. Puede ver toda la ruta de carga inspeccionando $ LOAD_PATH (un alias para $ :).

Como lib está en su ruta de carga, tiene dos opciones: o bien, nombre sus archivos con los mismos nombres que las constantes, de modo que Rails los recoja automáticamente cuando haga referencia a la constante en cuestión o exija explícitamente el módulo.

También noto que podrías estar confundido acerca de otra cosa. ApplicationController no es el objeto raíz en el sistema. Observar:

module MyModule def im_awesome puts "#{self} is so awesome" end end class ApplicationController < ActionController::Base include MyModule end class AnotherClass end AnotherClass.new.im_awesome # NoMethodError: undefined method `im_awesome'' for #<AnotherClass:0x101208ad0>

Deberá incluir el módulo en la clase en la que desee usarlo.

class AnotherClass include MyModule end AnotherClass.new.im_awesome # AnotherClass is so awesome

Por supuesto, para poder incluir el módulo en primer lugar, deberá tenerlo disponible (utilizando cualquiera de las técnicas anteriores).


Lo que funcionó para mí, además de descomentar config.autoload_paths (I''m on Rails 3.1.3), fue crear un inicializador como este:

#config/initializers/myapp_init.rb require ''my_module'' include MyModule

De esta forma puedo llamar a los métodos de mymodule desde cualquier lugar y como métodos de clase Model.mymodule_method o como métodos de instancia mymodel.mymodule_method

Quizás algún experto pueda explicar las implicaciones de esto. Por ahora, úsalo bajo tu propio riesgo.

Editar: Después, creo que una mejor aplicación sería:

crea un inicializador como este:

#config/initializers/myapp_init.rb require ‘my_module’

Incluya el módulo donde sea necesario, como este:

1) si desea usarlo como "Métodos de clase", use "extender":

class Myclass < ActiveRecord::Base extend MyModule def self.method1 Myclass.my_module_method end end

2) si desea usarlo como "Métodos de instancia", inclúyalo dentro de la definición de Clase:

class Myclass < ActiveRecord::Base include MyModule def method1 self.my_module_method end end

3) recuerde que include MyModule refiere a un archivo my_module.rb en su ruta de carga que primero debe ser requerido


Para usar el módulo lib/my_module.rb en sus modelos y controladores:

En config/application.rb :

config.watchable_dirs[''lib''] = [:rb]

En su modelo (idea similar para su controlador):

require_dependency ''my_module'' class MyModel < ActiveRecord::Base include MyModule MyModule.some_method end

Este método se describe con más detalle en http://hakunin.com/rails3-load-paths


Puede ser que desee cargar archivos de manera explícita en el directorio lib en el momento de la inicialización de la aplicación.
En mi config / application.rb, tengo una entrada como,
config.autoload_paths += %W(#{config.root}/lib)

También este podría ser el caso de que el nombre / jerarquía del módulo no sea el mismo que en el archivo o la ubicación / nombre del archivo no es lo mismo que esa jerarquía, por lo que tampoco es posible la carga automática de ese archivo. Entonces cuando agregué una entrada en la parte inferior de config / application.rb como,
require "./lib/file_name_without_extention
funcionó bien