2012-12-06 13 views
9

उठाता है मैं अपने रेल ऐप में फीचर ट्रेल को लागू कर रहा हूं। ऐसा करने के लिए, मैं वाईएएमएल में ऑब्जेक्ट को क्रमबद्ध कर रहा हूं। मुझे item_at_version विधि मिली है, जो मूल रूप से YAML::load(cached_object) करता है - यह बहुत अच्छी तरह से काम करता है, हालांकि, मुझे नहीं पता कि कभी-कभी यह undefined class/module _class name_ लौटाता है। यह इवेंट, वार्तालाप, नोट, और कई अन्य मॉडलों के साथ काम करता है, लेकिन बिना किसी कारण के, ऐसा लगता है कि डेटासेट, टिप्पणी, छात्र जैसे मॉडलों के लिए यह त्रुटि फेंकती है (मैंने इसके लिए कोई पैटर्न ढूंढने की कोशिश की है, बिना किसी किस्मत के)।वाईएएमएल :: लोड अपरिभाषित वर्ग/मॉड्यूल त्रुटि

मैं रेल 3.2.8, रूबी 1.9.3p327 का उपयोग कर रहा हूं, वाईएएमएल इंजन के रूप में मनोचिकित्सक (साइको :: संस्करण 1.3.4 लौटाता है)।

Ps। जब मैं उस फ़ाइल के शीर्ष पर 'model_name' जोड़ता हूं, तो यह एक आकर्षण की तरह काम करता है।

कोई भी विचार मुझे यह काम करने के लिए क्या बदलना/जोड़ना चाहिए?

संपादित करें: कोई ज्यादा कोड है जो मैं साझा कर सकते हैं:

def item_at_version 
    YAML::load(cached_object) 
end 

लेकिन शायद पश्व-अनुरेखन दिलचस्प होगा:

~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:312:in `path2class' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:312:in `resolve_class' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:219:in `visit_Psych_Nodes_Mapping' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/visitor.rb:15:in `visit' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/visitor.rb:5:in `accept' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:20:in `accept' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:238:in `visit_Psych_Nodes_Document' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/visitor.rb:15:in `visit' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/visitor.rb:5:in `accept' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:20:in `accept' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/nodes/node.rb:35:in `to_ruby' 
~/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych.rb:128:in `load' 
app/models/history_version.rb:7:in `item_at_version' 
app/controllers/history_controller.rb:8:in `show' 
actionpack (3.2.8) lib/action_controller/metal/implicit_render.rb:4:in `send_action' 
actionpack (3.2.8) lib/abstract_controller/base.rb:167:in `process_action' 
actionpack (3.2.8) lib/action_controller/metal/rendering.rb:10:in `process_action' 
actionpack (3.2.8) lib/abstract_controller/callbacks.rb:18:in `block in process_action' 
activesupport (3.2.8) lib/active_support/callbacks.rb:502:in `_run__1697733322876708236__process_action__1122943786273335015__callbacks' 
activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `__run_callback' 
activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_process_action_callbacks' 
activesupport (3.2.8) lib/active_support/callbacks.rb:81:in `run_callbacks' 
actionpack (3.2.8) lib/abstract_controller/callbacks.rb:17:in `process_action' 
actionpack (3.2.8) lib/action_controller/metal/rescue.rb:29:in `process_action' 
actionpack (3.2.8) lib/action_controller/metal/instrumentation.rb:30:in `block in process_action' 
activesupport (3.2.8) lib/active_support/notifications.rb:123:in `block in instrument' 
activesupport (3.2.8) lib/active_support/notifications/instrumenter.rb:20:in `instrument' 
activesupport (3.2.8) lib/active_support/notifications.rb:123:in `instrument' 
actionpack (3.2.8) lib/action_controller/metal/instrumentation.rb:29:in `process_action' 
actionpack (3.2.8) lib/action_controller/metal/params_wrapper.rb:207:in `process_action' 
activerecord (3.2.8) lib/active_record/railties/controller_runtime.rb:18:in `process_action' 
actionpack (3.2.8) lib/abstract_controller/base.rb:121:in `process' 
actionpack (3.2.8) lib/abstract_controller/rendering.rb:45:in `process' 
actionpack (3.2.8) lib/action_controller/metal.rb:203:in `dispatch' 
actionpack (3.2.8) lib/action_controller/metal/rack_delegation.rb:14:in `dispatch' 
actionpack (3.2.8) lib/action_controller/metal.rb:246:in `block in action' 
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:in `call' 
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:73:in `dispatch' 
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:36:in `call' 
journey (1.0.4) lib/journey/router.rb:68:in `block in call' 
journey (1.0.4) lib/journey/router.rb:56:in `each' 
journey (1.0.4) lib/journey/router.rb:56:in `call' 
actionpack (3.2.8) lib/action_dispatch/routing/route_set.rb:600:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/best_standards_support.rb:17:in `call' 
rack (1.4.1) lib/rack/etag.rb:23:in `call' 
rack (1.4.1) lib/rack/conditionalget.rb:25:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/head.rb:14:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/params_parser.rb:21:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/flash.rb:242:in `call' 
rack (1.4.1) lib/rack/session/abstract/id.rb:205:in `context' 
rack (1.4.1) lib/rack/session/abstract/id.rb:200:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/cookies.rb:339:in `call' 
activerecord (3.2.8) lib/active_record/query_cache.rb:64:in `call' 
activerecord (3.2.8) lib/active_record/connection_adapters/abstract/connection_pool.rb:473:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:28:in `block in call' 
activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `_run__2589517259026276185__call__1369641113040304056__callbacks' 
activesupport (3.2.8) lib/active_support/callbacks.rb:405:in `__run_callback' 
activesupport (3.2.8) lib/active_support/callbacks.rb:385:in `_run_call_callbacks' 
activesupport (3.2.8) lib/active_support/callbacks.rb:81:in `run_callbacks' 
actionpack (3.2.8) lib/action_dispatch/middleware/callbacks.rb:27:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/reloader.rb:65:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/remote_ip.rb:31:in `call' 
bugsnag (1.2.5) lib/bugsnag/rack.rb:35:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/debug_exceptions.rb:16:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/show_exceptions.rb:56:in `call' 
railties (3.2.8) lib/rails/rack/logger.rb:26:in `call_app' 
railties (3.2.8) lib/rails/rack/logger.rb:16:in `call' 
quiet_assets (1.0.1) lib/quiet_assets.rb:20:in `call_with_quiet_assets' 
actionpack (3.2.8) lib/action_dispatch/middleware/request_id.rb:22:in `call' 
rack (1.4.1) lib/rack/methodoverride.rb:21:in `call' 
rack (1.4.1) lib/rack/runtime.rb:17:in `call' 
activesupport (3.2.8) lib/active_support/cache/strategy/local_cache.rb:72:in `call' 
rack (1.4.1) lib/rack/lock.rb:15:in `call' 
actionpack (3.2.8) lib/action_dispatch/middleware/static.rb:62:in `call' 
railties (3.2.8) lib/rails/engine.rb:479:in `call' 
railties (3.2.8) lib/rails/application.rb:223:in `call' 
railties (3.2.8) lib/rails/railtie/configurable.rb:30:in `method_missing' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:147:in `handle' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:99:in `rescue in block (2 levels) in start' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:96:in `block (2 levels) in start' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:86:in `each' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:86:in `block in start' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:66:in `loop' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:66:in `start' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/lib/nack/server.rb:13:in `run' 
~/Library/Application Support/Pow/Versions/0.4.0/node_modules/nack/bin/nack_worker:4:in `<main>' 
+0

यदि आप कुछ प्रासंगिक कोड या बैकट्रैक दिखाते हैं तो आपको बेहतर सहायता मिल सकती है। – deefour

+0

मेरे कोड में जादू कुछ भी नहीं है, सह मेरे पास जोड़ने के लिए बहुत कुछ नहीं है। मैंने पूर्ण बैकट्रैक जोड़ा, शायद यह मदद कर सकता है। – user1105595

उत्तर

12

आप YAML.dump का उपयोग करते हैं रूबी में एक वस्तु को क्रमानुसार करने, वर्ग नाम का उपयोग यमल टैग के हिस्से के रूप में किया जाता है ताकि वस्तु को लोड करते समय सही वर्ग का उपयोग किया जा सके। उदाहरण के लिए:

require 'yaml' 

class Foo; end 

puts YAML.dump Foo.new 

पैदा करता

--- !ruby/object:Foo {} 

जब आप कि स्ट्रिंग पर YAML.load उपयोग करते हैं, साइक जानता है क्या वर्ग deserialized वस्तु के लिए दृष्टांत के लिए।

require 'yaml' 

# No Bar class has been defined 
YAML.load '--- !ruby/object:Bar {}' 

पैदा करता है:

आप एक YAML स्ट्रिंग है कि एक वर्ग है कि परिभाषित नहीं किया गया निर्दिष्ट करता है पर YAML.load कॉल करने के लिए कोशिश करते हैं, तो आप त्रुटि प्राप्त होगी

/Users/matt/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:312:in `path2class': undefined class/module Bar (ArgumentError) 
    from /Users/matt/.rvm/rubies/ruby-1.9.3-p327/lib/ruby/1.9.1/psych/visitors/to_ruby.rb:312:in `resolve_class' 
... 

यह वह जगह है क्योंकि मन को कक्षा Bar का उदाहरण बनाने की आवश्यकता है, लेकिन इसमें कक्षा की परिभाषा उपलब्ध नहीं है। यह बताता है कि यमल कार्यों को लोड करने से पहले require 'whatever' क्यों जोड़ना - अब रूबी के पास वर्ग की परिभाषा है और इसलिए इसका एक उदाहरण बना सकता है (ध्यान दें कि रूबी में कक्षा का नाम और फ़ाइल नाम के बीच कोई निश्चित लिंक नहीं है, यह सिर्फ सम्मेलन है)।

इसलिए समाधान यह सुनिश्चित करना है कि जब आप यमल से कोई रूबी ऑब्जेक्ट लोड कर रहे हों तो आपको पहले से ही ऐसी किसी भी फाइल की आवश्यकता हो सकती है जिसमें संभावित रूप से उस यमल में किसी भी कक्षा की परिभाषा हो।

+2

- आपके उत्तर के लिए धन्यवाद, हालांकि मुझे अभी भी यकीन नहीं है कि यह रेल में क्यों काम नहीं कर रहा है। जब मैं '' 'bar.new (कुछ:: पैरा) जोड़ता हूं,' '' यह काम करता है, तो ऑब्जेक्ट _should_ को तत्काल तत्काल भी काम करता है, है ना? – user1105595

+1

@ user1105595 यह दिलचस्प है। रेलों के ऑटोलोडिंग के साथ यह करना है। जब आप 'बार' नया करते हैं तो यह सामान्य ऑटोलोडिंग प्रक्रिया को ट्रिगर करता है, लेकिन यमल से deserializing नहीं करता है। यह आप अपने ऐप को उत्पादन में चलाते हैं (या सिर्फ 'cache_classes = true' के साथ) इसे काम करना चाहिए क्योंकि सभी कक्षाएं पहले ही लोड हो जाएंगी (शायद आप हर समय ऐसा नहीं करना चाहते हैं)। मुझे यकीन नहीं है कि सबसे अच्छा समाधान क्या है, आपको केवल प्रारंभिक या कुछ चीज़ों में फ़ाइलों की स्पष्ट आवश्यकता हो सकती है। – matt

+1

मुझे यह बग रिपोर्ट मिली है जो एक ही मुद्दे का जिक्र कर रही है (यह मार्शल के बारे में बात कर रही है, लेकिन 'rb_path_to_class' विधि वही है जो साइको में त्रुटि उत्पन्न कर रही है) http://bugs.ruby-lang.org/issues/3511 । – matt

2

Matt's Answer आवश्यक विवरण प्रदान करता है।

लेकिन जब मैं कोड में परिवर्तन करता हूं और फिर कुछ कार्य करता हूं, तो पेज लोड (AJAX में) के बिना कुछ डेटा को डी-सीरियलाइज करता है, तो यह एक ही त्रुटि के साथ विफल रहता है।

require से अपने परिवर्तनों को स्वत: लोड करने के लिए बेहतर है।

मॉड्यूल के मामले में (class के साथ परीक्षण नहीं किया गया है) और वाईएएमएल का उपयोग करके डी-सीरियलाइजिंग, आप इस समस्या को ठीक करने के लिए require के साथ डी-सीरियलाइजिंग से पहले अपने मॉड्यूल को तुरंत चालू कर सकते हैं। See here.

स्रोत: SO answer और Psych issue report in Github

पी.एस: यह समस्या config.cache_classes के रूप में केवल विकास में बनी रहती है उत्पादन में सक्षम है।

1

Matt's answer में संशोधन। एक शुद्ध-हैश आधारित समाधान (जो कि साइको टीम को करने में कोई रूचि नहीं है) के बदले, ऑब्जेक्ट वर्गीकरण को बंद करने के लिए हेडर स्ट्रिंग को संशोधित करें। मैंने बस निम्नलिखित कोड के साथ ऐसा किया।

yamltext = File.read("somefile","r") 
yamltext.sub!(/^--- \!.*$/,'---') 
hash = YAML.load(yamltext) 

यह असफल हो सकता है (मैं नहीं जानता) यदि इनपुट धारा अलग वस्तु classifiers (मुझे पता है न कि अगर भी मान्य है) के साथ कई दस्तावेजों के होते हैं।

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