我正在为open_flash_chart
插件编写自定义包装。它已放入其中,/lib
并作为模块加载到中ApplicationController
。
但是,我有一些类层次结构或smth问题。
我可以从任何控制器访问的open_flash_chart
功能OpenFlashChart
,Line
等等
但是,在/lib
模块的类中,它不起作用!
有任何想法吗?
Answers:
将文件加载到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)
config / application.rb中的内容被注释。
您可以尝试取消注释此行,或者,(对我而言,它甚至更好),请保留此注释(以供将来参考),并添加以下两行:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
../lib
路径ApplicationName::Application.config.autoload_paths
。
config.autoload_paths += Dir["#{config.root}/lib/**/"]
就足够了。@ckarbass第二行使您可以自由地将实用程序组织到子文件夹中,从而使用命名空间简化模块。就是这样。这就是更改默认设置的原因。迟到总比没有好:)
除了取消注释config.autoload_paths(我在Rails 3.1.3上)外,对我有用的是创建一个像这样的初始化程序:
#config/initializers/myapp_init.rb
require 'my_module'
include MyModule
这样,我可以在任何地方以类方法Model.mymodule_method
或实例方法调用mymodule方法mymodel.mymodule_method
也许有些专家可能会解释这一点的含义。现在,使用它需要您自担风险。
编辑:之后,我认为更好的方法是:
创建一个这样的初始化程序:
#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
文件夹中创建了模块,因此已添加config.autoload_paths += %W(#{config.root}/lib)
了config/application.rb
文件。之后,我按照您的建议添加config/initializers/myapp_init.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目录下的文件。
在我的config / application.rb中,我有一个条目, config.autoload_paths += %W(#{config.root}/lib)
也可能是模块名称/层次结构与文件中的名称不同或文件的位置/名称与该层次结构不同的情况,因此自动加载该文件也是不可能的。因此,当我在config / application.rb的底部添加一个条目时, require "./lib/file_name_without_extention
它工作正常。