Rails / lib模块和
我正在写一个open_flash_chart
插件的自定义包装。 它放在/lib
,并作为ApplicationController
一个模块加载。
但是,我有一些类层次结构或问题。
从任何控制器我可以访问OpenFlashChart
, Line
等open_flash_chart
function
但是,在一个/lib
模块的类中,它不起作用!
有任何想法吗?
有两种方法可以在Rails中加载文件:
- 它在自动加载过程中注册,并引用与文件名相对应的常量。 例如,如果你有
app/controllers/pages_controller.rb
和引用PagesController,app/controllers/pages_controller.rb
会自动加载。 这发生在加载path中的预设目录列表中。 这是Rails的一个特性,不是普通Ruby加载过程的一部分。 - 文件明确
require
d。 如果需要文件d,Ruby会查看加载path中的整个path列表,并find第一个require
的文件d在加载path中的情况。 您可以通过检查$ LOAD_PATH($的别名)来查看整个加载path。
因为lib
在你的加载path中,所以你有两个select:或者用与常量相同的名字来命名你的文件,这样Rails会在引用相关常量时自动select它们,或者明确地要求模块。
我也注意到你可能会对另一件事感到困惑。 ApplicationController 不是系统中的根对象。 注意:
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>
您将需要将模块包含到您想要使用的任何类中。
class AnotherClass include MyModule end AnotherClass.new.im_awesome # AnotherClass is so awesome
当然,为了能够将模块放在首位,您需要使用它(使用上述任一技术)。
在Rails 3 / lib模块不会自动加载。
这是因为行:
# config.autoload_paths += %W(#{config.root}/extras)
内部configuration/ application.rb被评论。
你可以尝试取消注释这一行,或者(对我来说它更好),留下这个评论(以供将来参考),并添加这两行:
config.autoload_paths += %W(#{config.root}/lib) config.autoload_paths += Dir["#{config.root}/lib/**/"]
除了取消注释config.autoload_paths(我在Rails 3.1.3上)之外,什么对我有效,是创build一个初始化程序,如下所示:
#config/initializers/myapp_init.rb require 'my_module' include MyModule
这样,我可以从任何地方调用mymodule方法,并作为类方法Model.mymodule_method
或作为实例方法mymodel.mymodule_method
也许有些专家可能会解释这一点的含义。 到现在为止,使用它需要您自担风险。
编辑:之后,我认为更好的approuch将是:
像这样创build一个初始化程序:
#config/initializers/myapp_init.rb require 'my_module'
在需要的地方join模块,如下所示:
1)如果你想使用它作为“类方法”使用“扩展”:
class Myclass < ActiveRecord::Base extend MyModule def self.method1 Myclass.my_module_method end end
2)如果你想使用它作为“实例方法”包括它在类定义:
class Myclass < ActiveRecord::Base include MyModule def method1 self.my_module_method end end
3)请记住, include MyModule
是指您的加载path中必须首先需要的文件my_module.rb
在模型和控制器中使用模块lib/my_module.rb
:
在config/application.rb
:
config.watchable_dirs['lib'] = [:rb]
在你的模型中(类似于你的控制器):
require_dependency 'my_module' class MyModel < ActiveRecord::Base include MyModule MyModule.some_method end
在应用程序初始化时,您可能会在lib目录下显式加载文件。
在我的config / application.rb中,我有一个条目,
config.autoload_paths += %W(#{config.root}/lib)
这也可能是模块名称/层次结构与文件中的不同,或者文件的位置/名称与该层次结构不同,因此该文件的自动加载也是不可能的。 所以当我在config / application.rb的底部添加一个条目时,
require "./lib/file_name_without_extention
它工作正常。