2009-07-02 14 views
76

मैं open_flash_chart प्लगइन के लिए एक कस्टम रैपर लिख रहा हूं। इसे /lib में रखा गया है और इसे ApplicationController में मॉड्यूल के रूप में लोड किया गया है।रेल/lib मॉड्यूल और

हालांकि, मेरे पास कुछ कक्षा पदानुक्रम या smth समस्या है।

किसी भी नियंत्रक से मैं open_flash_chart कार्यों OpenFlashChart के रूप में, Line आदि

एक /lib मॉड्यूल में उपयोग कर सकते हैं हालांकि, एक कक्षा में, यह काम नहीं करता है!

कोई विचार?

उत्तर

143

इन दो तरीकों फ़ाइलों रेल में लोड हो रहे हैं:

  • यह autoload प्रक्रिया में पंजीकृत है, और आप एक निरंतर कि फ़ाइल नाम से मेल खाती है के संदर्भ हैं। उदाहरण के लिए, यदि आपके पास app/controllers/pages_controller.rb और संदर्भ पृष्ठ नियंत्रक हैं, app/controllers/pages_controller.rb स्वचालित रूप से लोड हो जाएंगे। यह लोड पथ में निर्देशिकाओं की प्रीसेट सूची के लिए होता है। यह रेल की एक विशेषता है, और यह सामान्य रूबी लोड प्रक्रिया का हिस्सा नहीं है।
  • फ़ाइलें स्पष्ट रूप से require डी हैं। यदि कोई फ़ाइल require डी है, तो रूबी आपके लोड पथों में पथों की पूरी सूची देखती है, और पहला मामला ढूंढें जहां फ़ाइल require डी लोड पथ में है। आप $ LOAD_PATH ($ :) के लिए उपनाम का निरीक्षण करके संपूर्ण लोड पथ देख सकते हैं।

के बाद से lib अपनी लोड पथ में है, तो आप दो विकल्प हैं: या तो स्थिरांक के रूप में ही नाम के साथ आपकी फ़ाइलों के नामकरण, इसलिए रेल उन्हें स्वचालित रूप से लेने जाएगा जब आप प्रश्न में लगातार संदर्भ, या स्पष्ट रूप से की आवश्यकता होती है मॉड्यूल।

मुझे यह भी पता है कि आप किसी अन्य चीज़ के बारे में भ्रमित हो सकते हैं। एप्लिकेशन कंट्रोलर सिस्टम में रूट ऑब्जेक्ट नहीं है। का निरीक्षण करें:।

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 
बेशक

, क्रम में पहले स्थान पर मॉड्यूल शामिल करने के लिए सक्षम होने के लिए, आपको इसे उपलब्ध कराने की आवश्यकता होगी (ऊपर दी गई तकनीकों में से किसी एक का उपयोग करके)।

+2

पर अधिक विस्तार से वर्णित जोड़ना चाहता था: यदि आपके मॉड्यूल में से एक/lib (या ऑटोलोड निर्देशिका में से एक में) पहले ही परिभाषित किया गया है; उदाहरण के लिए आप ActiveRecord या स्ट्रिंग को अधिभारित करते हैं, आपको इसे स्पष्ट रूप से आवश्यकता होगी या इसे – Mike

+1

अजीब रूप से लोड नहीं किया जाएगा, मुझे मिल रहा है: अनन्य निरंतर GaClient (NameError), जब तक मुझे पहले 'ga_client' की आवश्यकता नहीं होती है (कक्षा को परिभाषित किया जाता है lib/ga_client.rb)। क्या ऑटोलोड नामकरण योजना के लिए दस्तावेज है? – mkirk

80

रेल 3/lib मॉड्यूल में स्वचालित रूप से लोड नहीं होते हैं।

# config.autoload_paths += %W(#{config.root}/extras) 

config अंदर/application.rb टिप्पणी की है:

इसका कारण यह है रेखा है।

आप (यह मेरे लिए और भी बेहतर काम किया) इस (भविष्य में संदर्भ के लिए) टिप्पणी की है और जोड़ने के इस दो पंक्तियों को छोड़ इस लाइन uncomment करने की कोशिश या, कर सकते हैं,:

config.autoload_paths += %W(#{config.root}/lib) 
config.autoload_paths += Dir["#{config.root}/lib/**/"] 
+0

यह 'application/ame' application.config.autoload_paths' सरणी में' ../ lib' पथ डुप्लिकेट करेगा। – jibiel

+1

@ जिबेल तो यहां संकल्प क्या है? – ylluminate

+0

मुझे नहीं पता लेकिन यह ठीक काम करता है .. :) – Orlando

19

क्या मेरे लिए काम किया, uncommenting के अलावा config.autoload_paths (मैं रेल 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) यदि आप "उदाहरण के तरीके" के रूप में उपयोग करना चाहते हैं तो यह वर्ग परिभाषा के अंदर में शामिल हैं:

class Myclass < ActiveRecord::Base 
include MyModule 
    def method1 
     self.my_module_method 
    end 
end 

3) याद रखें कि include MyModule अपनी लोड रास्ते में एक फ़ाइल my_module.rb कि पहले आवश्यक किया जाना चाहिए के लिए संदर्भित करता

+3

मैंने अपना मॉड्यूल 'lib' फ़ोल्डर पर बनाया है, इसलिए मैंने 'config.autoload_paths + =% W (# {config.root}/lib)'' config/application.rb' फ़ाइल 'पर जोड़ा है। इसके बाद मैंने 'config/startizers/myapp_init.rb' फ़ाइल और इसकी सामग्री जोड़ने के लिए आपके सुझाव का पालन किया। सबकुछ ठीक है। बहुत बहुत धन्यवाद :) –

+0

भले ही 'आवश्यकता' मेरे लिए काम करता है और ऑटो लोडिंग (अपरिभाषित मॉड्यूल विधि) नहीं है, [यह टिप्पणी कहती है कि आपको 'आवश्यकता' का उपयोग नहीं करना चाहिए (http://stackoverflow.com/questions/ 3356742/सबसे अच्छा तरह से करने के लिए लोड मॉड्यूल-वर्ग-से-लिब-फ़ोल्डर-रेल-3 में # comment3541227_3376401)। – Dennis

0

यह मामला हो सकता है कि आप एप्लिकेशन प्रारंभिकरण के समय lib निर्देशिका के तहत फ़ाइल को स्पष्ट रूप से लोड करना चाहते हैं।
मेरी कॉन्फ़िगरेशन/application.rb में, मेरे पास एक प्रविष्टि है,
config.autoload_paths += %W(#{config.root}/lib)

यह भी हो सकता है कि मॉड्यूल का नाम/पदानुक्रम समान नहीं है क्योंकि फ़ाइल या स्थान/फ़ाइल का नाम उस पदानुक्रम के समान नहीं है , इसलिए उस फ़ाइल का ऑटो लोड भी संभव नहीं है। तो जब मैंने config/application.rb के नीचे एक प्रविष्टि जोड़ा,
require "./lib/file_name_without_extention
यह ठीक काम करता था।

config/application.rb में:

config.watchable_dirs['lib'] = [:rb] 

अपने मॉडल (अपने नियंत्रक के लिए इसी तरह के विचार) में:

require_dependency 'my_module' 

class MyModel < ActiveRecord::Base 
    include MyModule 

    MyModule.some_method 
end 

इस विधि है

संबंधित मुद्दे