2009-03-25 13 views
12

मैं इस समस्या से चिपक गया हूँ।आप ActiveSupport :: JSON और JSON मणि के बीच संघर्ष से कैसे निपटते हैं?

ActiveSupport::JSON विभिन्न कोर ऑब्जेक्ट्स पर to_json परिभाषित करता है और इसलिए JSON मणि भी करता है। हालांकि, कार्यान्वयन समान नहीं है - ActiveSupport संस्करण तर्क लेता है और JSON मणि संस्करण नहीं करता है।

मैंने एक मणि स्थापित किया जिसके लिए JSON मणि और मेरा ऐप तोड़ दिया गया। मुद्दा यह है कि मैं एक नियंत्रक में to_json का उपयोग कर रहा हूं जो वस्तुओं की एक सूची देता है, लेकिन मैं नियंत्रित करना चाहता हूं कि कौन से गुण लौटाए गए हैं।

TypeError: wrong argument type Hash (expected Data)

मैं चीजें हैं जो मैं इसे ठीक करने के लिए ऑनलाइन पढ़ने के एक जोड़े की कोशिश की, लेकिन कुछ भी काम किया:

जब कोड अपने सिस्टम में कहीं भी require 'json' करता है मैं यह त्रुटि संदेश मिलता है। मैंने JSON.parse के बजाय ActiveSupport::JSON.decode का उपयोग करने के लिए मणि को फिर से लिखना समाप्त कर दिया।

यह काम करता है लेकिन यह टिकाऊ नहीं है ... मैं हर बार जब मैं एक मणि का उपयोग करना चाहता हूं जिसमें जेएसओएन मणि की आवश्यकता है तो मैं रत्नों को फोर्क नहीं कर सकता।

अद्यतन: इस समस्या का सबसे अच्छा समाधान रेल 2.3 या उच्चतम में अपग्रेड करना है, जो इसे ठीक करता है।

+1

क्यों इस सवाल के रूप में "समुदाय विकि" चिह्नित है? –

+0

मुझे नहीं पता, मैंने अभी सोचा कि मैं कोशिश करूँगा और देखें कि यह क्या करता है। –

+0

मुझे तुम्हारा दर्द महसूस हुआ है, मुझे उम्मीद है कि यह गड़बड़ कुछ दिन – MatthewFord

उत्तर

2

अद्यतनयह फ़िक्स केवल रेल < 2.3 पर लागू होता है। जैसा कि गिल्स नीचे उल्लेखित है, उन्होंने आंतरिक रूप से उसी तकनीक का उपयोग करके आंतरिक रूप से 2.3 में इसे ठीक किया है। लेकिन जेएसएस मणि के रेलवे संगतता (json/add/rails), पर पहले प्रयास से सावधान रहें, यदि आवश्यक हो तो स्पष्ट रूप से सब कुछ तोड़ देगा।

क्या आपका मतलब है require 'json' कथन स्वयं ही अपवाद उठाता है? या आपका मतलब है कि जब आप @something.to_json(:something => value) पर कॉल करते हैं तो आपको त्रुटि मिलती है? उत्तरार्द्ध वह है जो मैं उम्मीद करता हूं, अगर आपको JSON मणि की आवश्यकता होने में कोई समस्या है तो मुझे यकीन नहीं है कि क्या हो रहा है।

मैं सिर्फ ओथ मणि के साथ इस समस्या में भाग गया। मेरे मामले में, कोई सच्चा संघर्ष नहीं है, क्योंकि ओथ मणि to_json कार्यान्वयन पर निर्भर नहीं है। इसलिए समस्या यह है कि JSON ActiveSupport घोषणाओं को रोक रहा है। ActiveSupport लोड होने से पहले मैंने बस जेसन की आवश्यकता के साथ हल किया। लाना

require 'json' 

Rails::Initializer अंदर चाल किया था (हालांकि यह डालने के बाद ब्लॉक नहीं था)।

जो ActiveSupport को इसके बजाय डिफ़ॉल्ट JSON कार्यान्वयन को रोकने की अनुमति देता है।

अब यदि आप एक मणि का उपयोग कर रहे हैं जो वास्तव में to_json के JSON कार्यान्वयन पर निर्भर करता है तो आप एक क्रीक हैं। यह निश्चित रूप से मेटा प्रोग्रामिंग का सबसे खराब है, और मैं संघर्ष को हल करने के लिए रेल और जेएसओएन मणि डेवलपर्स के लिए वकालत करता हूं, हालांकि यह दर्दनाक होगा क्योंकि एक या दूसरे को पिछड़ा संगतता तोड़नी होगी।

अल्प अवधि में, मणि लेखक दोनों कार्यान्वयन का समर्थन करके अंतर को पुल करने में सक्षम हो सकते हैं। मणि विधि का उपयोग कैसे करता है इस पर निर्भर करता है कि यह कम या ज्यादा व्यवहार्य है। एक सबसे खराब स्थिति परिदृश्य एक आधिकारिक कांटा है (यानी gem और gem-rails)।

+0

हाँ हल हो जाएगी, मेरा मतलब है कि जब मैं किसी चीज का उपयोग करता हूं जिसे 'जेसन' की आवश्यकता होती है तो यह मुझे बहुत दर्द के कारण रेल_ज़ोन के रेल संस्करण को उड़ा देती है। आपके सुझावों के लिए धन्यवाद। क्या आपके पास 'जेसन/एड/रेल' की आवश्यकता के सुझाए गए विकल्प के साथ कोई भाग्य है? मैं इसे काम नहीं कर सकता। –

+0

केवल पहली बार कॉल करने की आवश्यकता होती है, इसलिए यदि आप रेल संस्करण लोड होने से पहले इसे कॉल करते हैं तो प्लगइन की आवश्यकता होने पर यह कुछ भी नहीं करेगा। मैंने इसे अभ्यास में सत्यापित कर लिया है, इसे रेल :: Initializer ब्लॉक में डाल दिया है। जेसन/ऐड/रेल चीज को लेकर कोई विचार नहीं है, लेकिन मुझे नहीं लगता कि यह आवश्यक है। – gtd

0

मुझे यकीन है कि उन्होंने इसे 2.3 में तय किया है लेकिन मुझे याद नहीं है कि कैसे।

+0

हाँ, मुझे लगता है कि वे सीधे to_json को कॉल करने से छुटकारा पा लिया। इसके बजाय आप as_json को परिभाषित करते हैं या आप JSON.generate या ActiveSupport :: JSON.encode को सीधे कॉल करते हैं। और नए JSON बैकएंड सामान के साथ, मुझे लगता है कि ActiveSupport :: JSON.encode आपकी पसंदीदा लाइब्रेरी का उपयोग करेगा। –

0

मैं इसे करने की कोशिश करना अभी तक है, लेकिन यह रेल की तरह 2.3.3 आप कुछ नियंत्रण देता दिखता है:

ActiveSupport::JSON.backend = 'JSONGem' 

Found here

+0

हाँ, रेल 2.3+ इस समस्या को हल करता है। –

0

मेरी अनूठा मामला हालांकि, मैं एक रूबी था में (गैर रेल) ऐप जो वास्तव में एक रेल ऐप लोड करता है (एक config/environment.rb लोड से) साथ ही कुछ रत्न जो जेसन का संदर्भ देता है। इससे मुझे इस तथ्य के कारण भारी सिरदर्द हुआ क्योंकि मैं रेल ऐप की पर्यावरण.आरबी फाइल को आसानी से बदल नहीं पाया। मैंने जेसन को डरावने टाइपरर को उठाए बिना काम करने के लिए कई रत्नों को तोड़ने का अंत किया: गलत तर्क प्रकार हैश (अपेक्षित डेटा) संदेश।

मैं जो मूल रूप से बुला अधिवक्ताओं 'active_support' की आवश्यकता से पहले 'json'

की आवश्यकता होती है इस समाधान है, जो ऊपर समुदाय विकी के जवाब के रूप में बिल्कुल विपरीत है के साथ कुछ भाग्य ... http://blog.swivel.com/code/2009/03/active-support-and-json-gems-dont-play-nice.html था

यह एकमात्र तरीका था जिसे मैं इसे काम कर सकता था, और मेरा विश्वास करो मैंने कई महीनों में सब कुछ करने की कोशिश की।

18

अद्यतन: रेल 3.2 के साथ भी, वही समस्या unfixed बनी हुई है। जेसन मणि जबरन लोड करने के लिए गंदा हैक और इसे ओवरराइट करें, यानी।

आखिरकार मैं सक्रिय कोड के to_json को पूरी तरह से बाईपास करने के लिए निम्न कोड के साथ समाप्त हुआ। इसे config/initializers/patches.rb में रखें, और आप JSON स्ट्रिंग जेनरेट करने के लिए {}.jsonize या [].jsonize कर सकते हैं। किसी भी चीज़ के साथ कोई संघर्ष नहीं, गारंटीकृत। कोड की

# Undo the effect of 'active_support/core_ext/object/to_json' 
require 'json' 
[Object, Array, Hash].each do |klass| 
    klass.class_eval <<-RUBY, __FILE__, __LINE__ 
    def jsonize(options = nil) 
     ::JSON.generate self, :quirks_mode => true 
    end 
    RUBY 
end 

8 लाइनों अपने अनुप्रयोग 50 बार JSON एन्कोडिंग के लिए तेजी से बनाते हैं। शायद आप वही करना चाहते हैं। :)


मुझे रेल 2.3.8 तक एक ही समस्या है।

समस्या यह है कि ActiveSupport::JSON.backend = 'JSONGem' आधा assed समाधान है और आपको अभी भी कुछ एन्कोडर्स को ओवरराइट करने की आवश्यकता है। (चेतावनी:। रेल 3.x, जो MultiJson का उपयोग करता है के लिए, यह ActiveSupport::JSON.backend = :json_gem कम से कम होना चाहिए, या यह चुपचाप नहीं सेशन हो जाएगा)

मेरे मामले में, मैं String#to_json क्योंकि JSON मणि 1.4 अधिलेखित करने के लिए की जरूरत है। 3 बेहतर है कि यह "\uXXXX" के रूप में गैर-एसीआई-लेकिन-वैध-यूटीएफ 8 अक्षरों को अंधाधुंध रूप से एन्कोड नहीं करता है, जहां यह आवश्यक नहीं है, इसलिए आपको छोटे बाइट्स (क्रमबद्ध करने के लिए अच्छा) और आसानी से पढ़ने के परिणाम मिलते हैं ("日本語""\u65e5\u672c\u8a9e" से मेरी आंखों के लिए बहुत कामुक दिखता है)।

यहाँ बंदर पैच है कि मैं का उपयोग किया गया है - जैसे config/initializers/patches.rb

module ActiveSupport 
    module JSON 
    module Encoding 
     class << self 
     def escape(string) 
      ::JSON.generate([string])[1..-2] 
     end 
     end 
    end 
    end 
end 

में निम्न कोड डालें और आप कुछ भी पर to_json का उपयोग करने के लिए स्वतंत्र हैं - स्ट्रिंग, सरणी और हैश।

+0

यह रेल 3.1.3 में इमोजी फिक्सिंग के साथ काम किया। धन्यवाद। – Chalkers

3

थोड़ी देर के लिए इस से जूझ के बाद .. मैंने पाया जा करने के लिए सरल समाधान:

if defined?(ActiveSupport::JSON) 
    [Object, Array, FalseClass, Float, Hash, Integer, NilClass, String, TrueClass].each do |klass| 
    klass.class_eval do 
    def to_json(*args) 
     super(args) 
    end 
    def as_json(*args) 
     super(args) 
    end 
    end 
    end 
end 

पुट कि activesupport के बाद कहीं भी भरी हुई है ..

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