سؤال

أنا في حيرة من هذه المشكلة.

ActiveSupport::JSON يحدد to_json على كائنات أساسية مختلفة وكذلك جوهرة JSON.ومع ذلك، فإن التنفيذ ليس هو نفسه - إصدار ActiveSupport يأخذ الوسائط بينما إصدار JSON Gem لا يأخذها.

لقد قمت بتثبيت جوهرة تتطلب جوهرة JSON وتعطل تطبيقي.المشكلة هي أنني أستخدم to_json في وحدة التحكم التي تُرجع قائمة بالكائنات، لكني أريد التحكم في السمات التي يتم إرجاعها.

عندما يفعل الكود في أي مكان في نظامي require 'json' أحصل على رسالة الخطأ هذه:

TypeError: wrong argument type Hash (expected Data)

لقد جربت بعض الأشياء التي قرأتها عبر الإنترنت لإصلاحها، لكن لم ينجح أي شيء.انتهى بي الأمر بإعادة كتابة الجوهرة لاستخدامها ActiveSupport::JSON.decode بدلاً من JSON.parse.

يعمل هذا ولكنه غير مستدام... لا يمكنني تشعب الجواهر في كل مرة أرغب فيها في استخدام جوهرة تتطلب جوهرة JSON.

تحديث: أفضل حل لهذه المشكلة هو الترقية إلى Rails 2.3 أو أعلى، مما أدى إلى حل المشكلة.

هل كانت مفيدة؟

المحلول

تحديث ينطبق هذا الإصلاح فقط على Rails <2.3.وكما يذكر جايلز أدناه، فقد قاموا بإصلاح هذه المشكلة في الإصدار 2.3 داخليًا باستخدام نفس التقنية تقريبًا.لكن احذر من محاولة json Gem السابقة للتوافق مع Rails (json/add/rails), والتي، إذا لزم الأمر صراحة سوف كسر كل شيء من جديد.

هل تقصد require 'json' البيان نفسه يثير هذا الاستثناء؟أو تقصد عند الاتصال @something.to_json(:something => value) تحصل على الخطأ؟الأخير هو ما أتوقعه، إذا كانت لديك مشكلة في طلب جوهرة JSON، فأنا لست متأكدًا مما يحدث.

لقد واجهت للتو هذه المشكلة مع جوهرة oauth.في حالتي، لا يوجد تعارض حقيقي، لأن جوهرة المصادقة لا تعتمد عليها to_json تطبيق.لذلك تكمن المشكلة في أن JSON يحجب إعلانات ActiveSupport.لقد قمت بحل هذه المشكلة ببساطة عن طريق طلب json قبل تحميل ActiveSupport.وضع

require 'json'

داخل Rails::Initializer لقد قام بالخدعة (على الرغم من عدم وضعها بعد الكتلة).

يتيح ذلك لـ ActiveSupport التغلب على تطبيق JSON الافتراضي بدلاً من ذلك.

الآن إذا كنت تستخدم جوهرة تعتمد فعليًا على تطبيق JSON لـ to_json فأنت فوق الخور.هذا بالتأكيد هو أسوأ ما في البرمجة الوصفية، وأود أن أدعو مطوري Rails وJSON Gem إلى حل هذا التعارض، على الرغم من أنه سيكون مؤلمًا لأنه سيتعين على أحدهما أو الآخر كسر التوافق مع الإصدارات السابقة.

على المدى القصير، قد يتمكن مؤلفو الأحجار الكريمة من سد الفجوة من خلال دعم كلا التطبيقين.يعد هذا ممكنًا إلى حد ما اعتمادًا على كيفية استخدام الجوهرة لهذه الطريقة.أسوأ السيناريوهات هو الشوكة الرسمية (أي. gem و gem-rails).

نصائح أخرى

تحديث:حتى مع الإصدار 3.2 من Rails، تظل نفس المشكلة دون حل.هذا هو الاختراق السيئ لتحميل جوهرة json بالقوة والكتابة فوقها.

في نهاية المطاف، انتهى بي الأمر بالكود التالي، لتجاوز ActiveSupport بالكامل to_json بالكامل.ضعها في config/initializers/patches.rb, ، ويمكنك القيام به {}.jsonize أو [].jsonize لإنشاء سلسلة JSON.لا يتعارض مع أي شيء، مضمونة.

# 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

الأسطر الثمانية من التعليمات البرمجية تجعل تطبيقك 50 مرة أسرع لتشفير JSON.ربما تريد أن تفعل الشيء نفسه.:)


لقد كنت أواجه مشكلة مماثلة حتى الإصدار 2.3.8 من Rails.

المشكلة هي ActiveSupport::JSON.backend = 'JSONGem' هو حل غير مؤكد وما زلت بحاجة إلى استبدال بعض برامج التشفير بنفسك.(تحذير:بالنسبة إلى Rails 3.x، الذي يستخدم MultiJson، يجب أن يكون كذلك ActiveSupport::JSON.backend = :json_gem على الأقل، أو سيكون بصمت عدم المرجع.)

في حالتي، كنت بحاجة إلى الكتابة String#to_json لأن JSON Gem 1.4.3 أفضل من حيث أنه لا يقوم بتشفير أحرف UTF8 غير ascii ولكن صالحة بشكل أعمى في شكل "\uXXXX" عندما لا يكون ذلك ضروريًا، حتى تحصل على بايتات أقصر (جيدة للتسلسل) ونتائج سهلة القراءة ("日本語" يبدو أكثر جنسية لعيني من "\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 على أي شيء - السلسلة والمصفوفة والتجزئة.

بعد مقاومة هذا لفترة من الوقت..لقد وجدت أن الحل الأبسط هو:

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

ضع ذلك في أي مكان بعد تحميل الدعم النشط..

أنا متأكد من أنهم أصلحوا هذه المشكلة في الإصدار 2.3 ولكن لا أتذكر كيف.

في حالتي، وإن كانت فريدة من نوعها، كان لدي تطبيق Ruby (غير تابع لـ Rails) والذي قام بالفعل بتحميل تطبيق Rails (من تحميل config/environment.rb) بالإضافة إلى بعض الأحجار الكريمة التي تشير إلى json.لقد سبب لي هذا صداعًا كبيرًا نظرًا لحقيقة أنني لم أتمكن ببساطة من تغيير ملف بيئة تطبيق Rails.rb.انتهى بي الأمر إلى تفرع عدد من الأحجار الكريمة من أجل جعل json يعمل دون رفع خطأ TypeError المخيف:وسيطة خاطئة اكتب رسالة التجزئة (البيانات المتوقعة).

لقد حالفني بعض الحظ في هذا الحل، وهو عكس تمامًا إجابة مجتمع ويكي أعلاه ...http://blog.swivel.com/code/2009/03/active-support-and-json-gems-dont-play-nice.htmlالذي يدعو الاتصال بشكل أساسي يتطلب "Active_support"قبل تتطلب "json"

كانت هذه هي الطريقة الوحيدة التي تمكنت من إنجاح الأمر، وصدقوني لقد جربت كل شيء على مدار عدة أشهر.

لم أجربه بعد، ولكن يبدو أن Rails 2.3.3 يمنحك بعض التحكم:

ActiveSupport::JSON.backend = 'JSONGem'

وجدت هنا

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top