我正在爲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