我正在为open_flash_chart
插件编写自定义封装。它被放置在/lib
中并作为模块加载到ApplicationController
中。Rails/lib模块和
但是,我有一些类层次结构或水手问题。
从任何控制器我可以访问open_flash_chart
功能OpenFlashChart
,Line
等
然而,在一个类中/lib
模块,它不工作!
任何想法?
我正在为open_flash_chart
插件编写自定义封装。它被放置在/lib
中并作为模块加载到ApplicationController
中。Rails/lib模块和
但是,我有一些类层次结构或水手问题。
从任何控制器我可以访问open_flash_chart
功能OpenFlashChart
,Line
等
然而,在一个类中/lib
模块,它不工作!
任何想法?
有一些文件Rails中得到加载两种方式:
app/controllers/pages_controller.rb
和引用PagesController,则会自动加载app/controllers/pages_controller.rb
。这发生在加载路径中的预设目录列表中。这是Rails的一个特性,并不是普通Ruby加载过程的一部分。require
d。如果文件为require
d,Ruby会查看加载路径中的整个路径列表,并找到第一个情况,即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/**/"]
这将复制`ApplicationName :: Application.config.autoload_paths`数组中的`../ lib`路径。 – jibiel 2012-01-23 11:30:56
什么工作对我来说,除了在取消config.autoload_paths(我在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)如果你想使用它作为“实例方法”包括IT类的定义中:
class Myclass < ActiveRecord::Base
include MyModule
def method1
self.my_module_method
end
end
3)记住,include MyModule
指的是在你的负载路径下的文件my_module.rb
必须需要首先
在应用程序初始化时,您可能需要在lib目录下显式加载文件。
在我的config/application.rb中,我有一个条目:config.autoload_paths += %W(#{config.root}/lib)
此外,这可能是模块名称/层次结构与文件中的不同,或者文件的位置/名称与该层次结构不同,因此该文件的自动加载也是不可能的。所以当我在config/application.rb底部添加一个条目时,它的效果很好,require "./lib/file_name_without_extention
。
使用模块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(或其中一个自动加载目录)中的某个模块已经定义;例如你重载ActiveRecord或String,你必须明确地要求它或它不会被加载 – Mike 2010-12-07 10:50:45
奇怪,我得到:未初始化的常量GaClient(NameError),除非我需要事先'ga_client'(类定义在LIB/ga_client.rb)。是否有自动加载命名方案的文档? – mkirk 2011-04-15 20:58:21