Rails / lib módulos e

Estou escrevendo um wrapper personalizado para o open_flash_chart in open_flash_chart . Ele é colocado em /lib e carregado como um módulo no ApplicationController .

No entanto, tenho alguma hierarquia de classs ou problema de smth.

De qualquer controlador eu posso acessar open_flash_chart funções OpenFlashChart como OpenFlashChart , Line etc

No entanto, em uma class em um módulo /lib , ele não funciona!

Alguma ideia?

Existem duas maneiras de carregar arquivos no Rails:

  • Ele está registrado no processo de carregamento automático e você faz referência a uma constante que corresponde ao nome do arquivo. Por exemplo, se você tiver o app/controllers/pages_controller.rb e o PagesController, o app/controllers/pages_controller.rb será automaticamente carregado. Isso acontece para uma lista predefinida de diretórios no caminho de carregamento. Este é um recurso do Rails e não faz parte do processo de carregamento normal do Ruby.
  • Arquivos são explicitamente require d. Se um arquivo for require d, Ruby examinará toda a lista de caminhos nos caminhos de carregamento e localizará o primeiro caso em que o arquivo require está no caminho de carregamento. Você pode ver todo o caminho de carregamento inspecionando $ LOAD_PATH (um alias para $ :).

Como o lib está no seu caminho de carregamento, você tem duas opções: nomear seus arquivos com os mesmos nomes das constantes, então o Rails os pegará automaticamente quando você fizer referência à constante em questão ou exigir explicitamente o módulo.

Eu também noto que você pode estar confuso sobre outra coisa. ApplicationController não é o object raiz no 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 # 

Você precisará include o módulo em qualquer class na qual deseja usá-lo.

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

É claro que, para poder include o módulo em primeiro lugar, você precisará disponibilizá-lo (usando uma das técnicas acima).

No Rails 3 / lib os módulos não são carregados automaticamente.

Isso é porque a linha:

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

dentro config / application.rb é comentado.

Você pode tentar descomentar esta linha ou, (funcionou ainda melhor para mim), deixe este comentário (para referência futura) e adicione estas duas linhas:

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

O que funcionou para mim, além de descomentar o config.autoload_paths (estou no Rails 3.1.3), foi criar um inicializador como este:

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

Desta forma eu posso chamar methods mymodule de qualquer lugar e como methods de class Model.mymodule_method ou como methods de instância mymodel.mymodule_method

Talvez algum especialista possa explicar as implicações disso. Até agora, use-o por sua conta e risco.

Edit: Depois, eu acho que um melhor approuch seria:

crie um inicializador como este:

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

Inclua o módulo onde for necessário, assim:

1) se você quiser usá-lo como “Class Methods” use “extend”:

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

2) se você quiser usá-lo como "Instance Methods" inclua dentro da definição de class:

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

3) lembre-se que include MyModule refere-se a um arquivo my_module.rb no seu caminho de carregamento que deve ser necessário primeiro

Para usar o módulo lib/my_module.rb em seus modelos e controladores:

Em config/application.rb :

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

Em seu modelo (idéia semelhante para o seu controlador):

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

Este método é descrito em mais detalhes em http://hakunin.com/rails3-load-paths

Pode ser o caso de você querer carregar explicitamente o (s) arquivo (s) no diretório lib no momento da boot do aplicativo.
Na minha configuração / application.rb, eu tenho uma input como,
config.autoload_paths += %W(#{config.root}/lib)

Além disso, pode ser que o nome / hierarquia do módulo não seja igual ao do arquivo ou a localização / nome do arquivo não seja a mesma hierarquia, portanto, o carregamento automático desse arquivo também não é possível. Então, quando eu adicionei uma input na parte inferior do config / application.rb como,
require "./lib/file_name_without_extention
funcionou bem.