我正在为open_flash_chart
插件编写自定义包装器。它放在/lib
中,并将其加载为ApplicationController
中的模块。
但是,我有一些Class层次结构或smth问题。
在任何控制器中,我都可以open_flash_chart
,OpenFlashChart
等访问Line
个功能
但是,在/lib
模块中的一个类中,它不起作用!
有什么想法吗?
答案 0 :(得分:145)
有两种方法可以在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
当然,为了能够首先包含该模块,您需要使用它(使用上述任何一种技术)。
答案 1 :(得分:84)
在Rails 3 / lib模块中不会自动加载。
这是因为行:
# config.autoload_paths += %W(#{config.root}/extras)
在config / application.rb中注释。
你可以尝试取消注释这一行,或者(对我来说效果更好),留下这个评论(以备将来参考)并添加这两行:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
答案 2 :(得分:21)
除了取消注释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)如果你想将它用作“类方法”,请使用“extend”:
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
答案 3 :(得分:2)
在模型和控制器中使用模块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
中有更详细的描述
答案 4 :(得分:0)
可能是您希望在应用程序初始化时在lib目录下显式加载文件的情况。
在我的config / application.rb中,我有一个条目, config.autoload_paths += %W(#{config.root}/lib)
也可能是模块名称/层次结构与它位于文件或位置/文件名与该层次结构不同,因此也无法自动加载该文件。所以当我在config / application.rb底部添加一个条目时,为 require "./lib/file_name_without_extention
,它工作正常。