Estoy escribiendo un contenedor personalizado para el open_flash_chart
complemento. Se coloca /lib
y se carga como un módulo en ApplicationController
.
Sin embargo, tengo algún problema de jerarquía de clases o algo.
Desde cualquier controlador puedo acceder a open_flash_chart
funciones como OpenFlashChart
, Line
etc.
Sin embargo, en una clase en un /lib
módulo, ¡no funciona!
¿Algunas ideas?
ruby-on-rails
ruby
class
module
Mantas
fuente
fuente
Respuestas:
Hay dos formas de cargar archivos en Rails:
app/controllers/pages_controller.rb
referencia a PagesController, seapp/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 de carga normal de Ruby.require
d. Si un archivo esrequire
d, Ruby busca en toda la lista de rutas en sus rutas de carga y encuentra el primer caso donde el archivo querequire
d está en la ruta de carga. Puede ver la ruta de carga completa inspeccionando $ LOAD_PATH (un alias para $ :).Como
lib
está en su ruta de carga, tiene dos opciones: nombrar sus archivos con los mismos nombres que las constantes, por lo que Rails los recogerá automáticamente cuando haga referencia a la constante en cuestión, o requiera explícitamente el módulo.También me doy cuenta de que podría estar confundido por otra cosa. ApplicationController no es el objeto raíz del 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).
fuente
En Rails 3 / lib, los módulos no se cargan automáticamente.
Esto se debe a que la línea:
# config.autoload_paths += %W(#{config.root}/extras)
dentro de config / application.rb está comentado.
Puede intentar descomentar esta línea o, (funcionó aún mejor para mí), dejar esto comentado (para referencia futura) y agregar estas dos líneas:
config.autoload_paths += %W(#{config.root}/lib) config.autoload_paths += Dir["#{config.root}/lib/**/"]
fuente
../lib
ruta en laApplicationName::Application.config.autoload_paths
matriz.config.autoload_paths += Dir["#{config.root}/lib/**/"]
debería ser suficiente. @ckarbass La segunda línea le da la libertad de organizar sus utilidades en subcarpetas y así mejorar sus módulos con espacios de nombres . Eso es practicamente todo. Y aquí está la razón por la que se cambió el valor predeterminado. Más vale tarde que nunca :)Lo que funcionó para mí, además de descomentar config.autoload_paths (estoy en Rails 3.1.3), fue crear un inicializador como este:
#config/initializers/myapp_init.rb require 'my_module' include MyModule
De esta manera puedo llamar a los métodos mymodule desde cualquier lugar y como métodos de clase
Model.mymodule_method
o como métodos de instanciamymodel.mymodule_method
Quizás algún experto pueda explicar las implicaciones de esto. Por ahora, utilícelo bajo su 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, así:
1) si desea utilizarlo como "Métodos de clase", utilice "extender":
class Myclass < ActiveRecord::Base extend MyModule def self.method1 Myclass.my_module_method end end
2) si desea utilizarlo 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 se
include MyModule
refiere a un archivomy_module.rb
en su ruta de carga que debe ser requerido primerofuente
lib
carpeta, por lo tanto, lo he agregadoconfig.autoload_paths += %W(#{config.root}/lib)
en elconfig/application.rb
archivo. Después de eso, seguí su sugerencia para agregar unconfig/initializers/myapp_init.rb
archivo y su contenido. Todo es bueno. Muchas gracias :)require
funciona para mí y la carga automática no (método de módulo indefinido), este comentario dice que no debes usarrequire
.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
fuente
Puede darse el caso de que desee cargar explícitamente archivos 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 / el nombre del archivo no es el mismo que esa jerarquía, por lo que la carga automática de ese archivo tampoco es posible. Entonces, cuando agregué una entrada en la parte inferior de config / application.rb as,
require "./lib/file_name_without_extention
funcionó bien.
fuente