我写了一个自定义包装open_flash_chart
插件。 它放置在/lib
,并加载它作为一个模块ApplicationController
。
不过,我有一些类层次结构或不便的问题。
从任何控制器我可以访问open_flash_chart
功能OpenFlashChart
, Line
等
然而,在一个类中的/lib
模块,它不工作!
有任何想法吗?
我写了一个自定义包装open_flash_chart
插件。 它放置在/lib
,并加载它作为一个模块ApplicationController
。
不过,我有一些类层次结构或不便的问题。
从任何控制器我可以访问open_flash_chart
功能OpenFlashChart
, Line
等
然而,在一个类中的/lib
模块,它不工作!
有任何想法吗?
有迹象表明,文件Rails中得到加载两种方式:
app/controllers/pages_controller.rb
和参考PagesController, app/controllers/pages_controller.rb
会自动加载。 这发生在负载路径目录的预设列表。 这是轨道的特征,并且不是一般的Ruby负载过程的一部分。 require
d。 如果文件是require
d,红宝石看起来通过在负载路径路径的整个列表,并找到你的文件,第一种情况require
d是在负载路径。 您可以通过检查$ LOAD_PATH(为$ :)别名看到整个负载路径。 由于lib
是在您的负载路径,你有两个选择:要么与名称相同名称的常量的文件,这样Rails会自动接他们,当你引用常数问题,或明确要求的模块。
我也注意到,你可能会感到困惑的另一件事。 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)
内部配置/ application.rb中被注释。
你可以试着去掉这一行,或者(它为我工作更好),离开这个评论(备查),并添加这两条线:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
什么工作对我来说,除了在取消config.autoload_paths(我on Rails的3.1.3),是要创造一个像这样的初始化:
#config/initializers/myapp_init.rb
require 'my_module'
include MyModule
这样我可以调用MyModule的方法在任何地方和类方法Model.mymodule_method
或实例方法mymodel.mymodule_method
也许有些专家可以解释这意味着什么。 现在,在你自己的风险使用它。
编辑:后来,我想一个更好的approuch是:
创建这样的初始化:
#config/initializers/myapp_init.rb
require ‘my_module’
包括在需要的地方,这样的模块:
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
是一个文件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
该方法更详细描述在http://hakunin.com/rails3-load-paths
这可能是你想在应用程序初始化的时间显式地加载lib目录下的文件(S)的情况下。
在我的config / application.rb中,我有一个条目,
config.autoload_paths += %W(#{config.root}/lib)
这也可能是模块名称/层次是不相同的情况下,因为它是在文件或位置/文件名不一样的层次结构,使文件自动负载也是不可能的。 所以,当我在配置/ application.rb中为底部增加了一个入口,
require "./lib/file_name_without_extention
它工作得很好。