रेल / कामगार मॉड्यूल और


83

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

हालाँकि, मुझे कुछ क्लास पदानुक्रम या एसएमएस समस्या है।

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

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

कोई विचार?


उम्मीद है कि यह आपकी मदद कर सकता है stackoverflow.com/questions/17304110/…
यादव

जवाबों:


147

वहाँ दो तरीके हैं कि फ़ाइलें रेल में भरी हुई हैं:

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

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

मैं यह भी नोटिस करता हूं कि आप किसी अन्य चीज़ के बारे में भ्रमित हो सकते हैं। 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

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


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

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

87

रेल में 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
जिबील

1
@ जिजीएल तो यहाँ क्या संकल्प है?
यूलुमिनेट करें

4
आपके लिए बाद वाला विकल्प बेहतर क्यों रहा? इसके अलावा, डिफ़ॉल्ट को क्यों बदला गया ... बहुत से लोगों को काम करने के बावजूद एक कारण होना चाहिए।
ckarbass

@ylluminate इतना एकल config.autoload_paths += Dir["#{config.root}/lib/**/"]पर्याप्त होना चाहिए। @ckarbass दूसरी पंक्ति आपको अपनी उपयोगिताओं को सबफ़ोल्डर में व्यवस्थित करने की स्वतंत्रता देती है और इस प्रकार अपने मॉड्यूल को नामस्थानों के साथ उठाती है । तो इतना ही है। और यहाँ क्यों डिफ़ॉल्ट को बदल दिया गया था। देर से कभी भी बेहतर नहीं :)
jibiel

यह मुझे थोड़ा गड़बड़ लगता है। क्या यह अनावश्यक रूप से ऑटो-लोड रेक कार्य नहीं होगा?
डेनिस

22

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/initializers/myapp_init.rbफ़ाइल जोड़ने के आपके सुझाव का पालन किया और यह सामग्री है। सबकुछ ठीक है। बहुत बहुत धन्यवाद :)
SMMousavi

हालांकि requireमेरे और ऑटो-लोडिंग के लिए काम नहीं करता है (अपरिभाषित मॉड्यूल विधि), यह टिप्पणी कहती है कि आपको इसका उपयोग नहीं करना चाहिएrequire
डेनिस

3

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 पर अधिक विस्तार से वर्णित किया गया है


0

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

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.