Ruby-on-rails Rails /lib 模块和
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1073076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails /lib modules and
提问by Mantas
I am writing a custom wrapper for open_flash_chartplugin. It's placed in /liband load it as a module in ApplicationController.
我正在为open_flash_chart插件编写自定义包装器。它被放置/lib在ApplicationController.
However, I have some Class hierarchy or smth problem.
但是,我有一些类层次结构或 smth 问题。
From any controller I can access open_flash_chartfunctions as OpenFlashChart, Lineetc
从任何控制器我都可以访问open_flash_chart功能OpenFlashChart,Line等等
However, in a class in a /libmodule, it doesnt work!
但是,在/lib模块中的类中,它不起作用!
Any ideas?
有任何想法吗?
回答by Yehuda Katz
There are two ways that files get loaded in Rails:
在 Rails 中加载文件有两种方式:
- It is registered in the autoload process, and you reference a constant that corresponds to the file name. For instance, if you have
app/controllers/pages_controller.rband reference PagesController,app/controllers/pages_controller.rbwill automatically be loaded. This happens for a preset list of directories in the load path. This is a feature of Rails, and is not part of the normal Ruby load process. - Files are explicitly
required. If a file isrequired, Ruby looks through the entire list of paths in your load paths, and find the first case where the file yourequired is in the load path. You can see the entire load path by inspecting $LOAD_PATH (an alias for $:).
- 它在自动加载过程中注册,您引用与文件名对应的常量。例如,如果你有
app/controllers/pages_controller.rb并引用 PagesController,app/controllers/pages_controller.rb就会自动加载。这发生在加载路径中的预设目录列表中。这是 Rails 的一个特性,不是正常 Ruby 加载过程的一部分。 - 文件是明确的
required。如果文件是required,Ruby 会查看加载路径中的整个路径列表,并找到您required的文件在加载路径中的第一种情况。您可以通过检查 $LOAD_PATH($: 的别名)来查看整个加载路径。
Since libis in your load path, you have two options: either name your files with the same names as the constants, so Rails will automatically pick them up when you reference the constant in question, or explicitly require the module.
因为lib是在你的加载路径中,所以你有两个选择:要么用与常量相同的名称命名你的文件,这样当你引用有问题的常量时 Rails 会自动选择它们,要么明确要求模块。
I also notice that you might be confused about another thing. ApplicationController is notthe root object in the system. Observe:
我还注意到您可能对另一件事感到困惑。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>
You will need to include the module into whatever class you want to use it in.
您需要将该模块包含在您想要使用它的任何类中。
class AnotherClass
include MyModule
end
AnotherClass.new.im_awesome
# AnotherClass is so awesome
Of course, in order to be able to include the module in the first place, you'll need to have it available (using either of the techniques above).
当然,为了能够首先包含该模块,您需要使其可用(使用上述任一技术)。
回答by diegopau
In Rails 3 /lib modules are not loaded automatically.
在 Rails 3 中,/lib 模块不会自动加载。
This is because the line:
这是因为该行:
# config.autoload_paths += %W(#{config.root}/extras)
inside config/application.rb is commented.
里面的 config/application.rb 被注释了。
You can try to uncomment this line or, (it worked even better for me), leave this commented (for future reference) and add this two lines:
您可以尝试取消注释此行,或者(它对我来说效果更好),留下注释(以供将来参考)并添加以下两行:
config.autoload_paths += %W(#{config.root}/lib)
config.autoload_paths += Dir["#{config.root}/lib/**/"]
回答by Fernando Fabreti
What worked for me, besides uncommenting config.autoload_paths (I'm on Rails 3.1.3), was to create a initializer like this:
除了取消注释 config.autoload_paths(我在 Rails 3.1.3 上)之外,对我有用的是创建一个这样的初始化程序:
#config/initializers/myapp_init.rb
require 'my_module'
include MyModule
This way I can call mymodule methods from anywhereand as class methods Model.mymodule_methodor as instance methods mymodel.mymodule_method
这样我就可以从任何地方调用 mymodule 方法,作为类方法Model.mymodule_method或实例方法mymodel.mymodule_method
Maybe some expert may explain the implications of this. By now, use it at your own risk.
也许某些专家可能会解释这一点的含义。到目前为止,请自行承担使用它的风险。
Edit:Afterwards, I think a better approuch would be:
编辑:之后,我认为更好的方法是:
create a initializer like this:
创建一个这样的初始化程序:
#config/initializers/myapp_init.rb
require ‘my_module'
Include the module where needed, like this:
在需要的地方包含模块,如下所示:
1) if you want to use it as "Class Methods" use "extend":
1) 如果要将其用作“类方法”,请使用“扩展”:
class Myclass < ActiveRecord::Base
extend MyModule
def self.method1
Myclass.my_module_method
end
end
2) if you want to use it as "Instance Methods" include it inside Class definition:
2)如果您想将其用作“实例方法”,请将其包含在类定义中:
class Myclass < ActiveRecord::Base
include MyModule
def method1
self.my_module_method
end
end
3) remember that include MyModulerefers to a file my_module.rbin your load path that must be required first
3)记住,include MyModule是指my_module.rb加载路径中必须首先需要的文件
回答by Dennis
To use the module lib/my_module.rbin your models and controllers:
要lib/my_module.rb在您的模型和控制器中使用该模块:
In config/application.rb:
在config/application.rb:
config.watchable_dirs['lib'] = [:rb]
In your model (similar idea for your controller):
在您的模型中(控制器的类似想法):
require_dependency 'my_module'
class MyModel < ActiveRecord::Base
include MyModule
MyModule.some_method
end
This method is described in more detail at http://hakunin.com/rails3-load-paths
此方法在http://hakunin.com/rails3-load-paths中有更详细的描述
回答by Swapnil Chincholkar
It might be the case that you want to explicitly load file(s) under lib directory at time of application initialization.
In my config/application.rb, I have an entry as, config.autoload_paths += %W(#{config.root}/lib)
Also this might be the case that module name/hierarchy is not same as it is in file or location/name of file is not same as that hierarchy, so auto-load of that file is also not possible. So when I added an entry at bottom of config/application.rb as, require "./lib/file_name_without_extention
it worked fine.
您可能希望在应用程序初始化时显式加载 lib 目录下的文件。
在我的 config/application.rb 中,我有一个条目,config.autoload_paths += %W(#{config.root}/lib)
这也可能是模块名称/层次结构与文件中的不同,或者文件的位置/名称与该层次结构不同,因此自动加载那个文件也是不可能的。所以当我在 config/application.rb as 底部添加一个条目时,require "./lib/file_name_without_extention
它工作正常。

