কীভাবে কারাগুলিতে to_json ওভাররাইড করবেন?


94

হালনাগাদ:

এই সমস্যাটি সঠিকভাবে অনুসন্ধান করা হয়নি। আসল ইস্যুর মধ্যেই রয়েছে render :json

মূল প্রশ্নে প্রথম কোড পেস্ট প্রত্যাশিত ফলাফল দেবে। তবে, এখনও একটি সতর্কতা অবলম্বন আছে। এই উদাহরণটি দেখুন:

render :json => current_user

হয় না হিসাবে একই

render :json => current_user.to_json

অর্থাৎ, ব্যবহারকারী অবজেক্টের সাথে যুক্ত পদ্ধতিটি render :jsonস্বয়ংক্রিয়ভাবে কল করবে না to_jsonআসলে , যদি মডেলটিতে to_jsonওভাররাইড করা হয় তবে নীচে বর্ণিতটি উত্পন্ন করবে ।Userrender :json => @userArgumentError

সারসংক্ষেপ

# works if User#to_json is not overridden
render :json => current_user

# If User#to_json is overridden, User requires explicit call
render :json => current_user.to_json

এগুলি আমার কাছে নির্বোধ বলে মনে হচ্ছে। এটি আমাকে বলছে বলে মনে হচ্ছে যে টাইপ নির্দিষ্ট করা হলে renderআসলে কল করা হয় না । এখানে কি ঘটছে তা কেউ ব্যাখ্যা করতে পারেন?Model#to_json:json

যে কোনও জিনিয়াই আমাকে এটির সাহায্য করতে পারে তা সম্ভবত আমার অন্যান্য প্রশ্নের উত্তর দিতে পারে: কীভাবে জেলগুলিতে @ foo.to_json (বিকল্পগুলি) এবং @ বার্স.টো_জসন (বিকল্পগুলি) একত্রিত করে JSON প্রতিক্রিয়া তৈরি করতে হবে?


মূল প্রশ্ন:

আমি এসও-তে আরও কয়েকটি উদাহরণ দেখেছি, তবে আমি যা খুঁজছি তা কিছুই করি না।

আমি চেষ্টা করছি:

class User < ActiveRecord::Base

  # this actually works! (see update summary above)
  def to_json
    super(:only => :username, :methods => [:foo, :bar])
  end

end

আমি পেয়ে করছি ArgumentError: wrong number of arguments (1 for 0)মধ্যে

/usr/lib/ruby/gems/1.9.1/gems/activesupport-2.3.5/lib/active_support/json/encoders/object.rb:4:in `to_json

কোন ধারনা?


আপনার উদাহরণটি আমার মডেলগুলির একটিতে কাজ করে। username, fooবা barপদ্ধতিগুলির কোনও আর্গুমেন্ট আশা করে?
জোনাথন জুলিয়ান

না, usernameএকটি পদ্ধতি এবং নয় fooএবং barপদ্ধতি প্রয়োজন হয় না। ত্রুটিটি কোথায় ঘটছে তা দেখাতে আমি আমার প্রশ্ন আপডেট করেছি।
maček

আমি 1.8.7 চালাচ্ছি। আপনাকে সেই ফাইলটি খুলতে হবে এবং দেখতে হবে কেন এটি শূন্য আরগের প্রত্যাশা করে এমন কোনও পদ্ধতিতে একটি আর্গ পাস করছে।
জোনাথন জুলিয়ান

উত্তর:


216

আপনি পাচ্ছেন ArgumentError: wrong number of arguments (1 for 0)কারণ to_jsonএকটি প্যারামিটার, optionsহ্যাশ দিয়ে ওভাররাইড করা দরকার ।

def to_json(options)
  ...
end

আর ব্যাখ্যা to_json, as_jsonএবং রেন্ডারিং:

অ্যাক্টিভস্পোর্টে ২.৩.৩-তে as_jsonআপনার মুখোমুখি সমস্যার মতো বিষয়গুলি যুক্ত করার জন্য যুক্ত করা হয়েছিল। সৃষ্টি JSON এর থেকে পৃথক হওয়া উচিত রেন্ডারিং JSON করুন।

এখন, যে কোনও সময় to_jsonকোনও বস্তুর উপরে ডাকা হয়, as_jsonডেটা স্ট্রাকচার তৈরি করতে অনুরোধ করা হয় এবং তারপরে সেই হ্যাশটিকে JSON স্ট্রিং হিসাবে এনকোড করা হয় ActiveSupport::json.encode। এটি সমস্ত ধরণের ক্ষেত্রে ঘটে: বস্তু, সংখ্যা, তারিখ, স্ট্রিং ইত্যাদি (অ্যাক্টিভসপোর্ট কোড দেখুন)।

অ্যাক্টিভেকর্ড অবজেক্টগুলি একইভাবে আচরণ করে। একটি ডিফল্ট as_jsonবাস্তবায়ন রয়েছে যা একটি হ্যাশ তৈরি করে যা এতে মডেলের সমস্ত বৈশিষ্ট্য অন্তর্ভুক্ত করে। আপনি as_jsonচান JSON কাঠামো তৈরি করতে আপনার মডেলটিতে ওভাররাইড করা উচিতas_jsonপুরানোের মতোই to_json, একটি বিকল্প হ্যাশ নেয় যেখানে আপনি বৈশিষ্ট্যযুক্ত এবং বর্ণনামূলকভাবে অন্তর্ভুক্ত করার পদ্ধতিগুলি নির্দিষ্ট করতে পারেন।

def as_json(options)
  # this example ignores the user's options
  super(:only => [:email, :handle])
end

আপনার নিয়ামকটিতে, render :json => oএকটি স্ট্রিং বা কোনও অবজেক্ট গ্রহণ করতে পারেন। যদি এটি একটি স্ট্রিং হয়, তবে এটি প্রতিক্রিয়া হিসাবে চিহ্নিত হবে, যদি এটি কোনও বস্তু to_jsonহয় তবে তাকে বলা হয়, যা as_jsonউপরে বর্ণিত হিসাবে ট্রিগার করে ।

সুতরাং, যতক্ষণ না আপনার মডেলগুলি যথাযথভাবে as_jsonওভাররাইডগুলি (বা না) দিয়ে উপস্থাপিত হয়, ততক্ষণ একটি মডেল প্রদর্শন করার জন্য আপনার নিয়ামক কোডটি দেখতে দেখতে এটি দেখতে পারা উচিত:

format.json { render :json => @user }

গল্পটির নৈতিকতা হ'ল: সরাসরি ফোন to_jsonকরা এড়িয়ে চলুন , renderআপনার পক্ষে এটি করার অনুমতি দিন । আপনার যদি জেএসএন আউটপুট টুইঙ্ক করার প্রয়োজন হয়, কল করুন as_json

format.json { render :json => 
    @user.as_json(:only => [:username], :methods => [:avatar]) }

@ জোনাথন জুলিয়ান, এটির একটি খুব সহায়ক ব্যাখ্যা as_json। আপনি যেমন অ্যাক্টিভেকর্ড :: সিরিয়ালাইজেশন ডক্স ( api.rubyonrails.org/classes/ActiveRecord/… ) এ দেখতে পাচ্ছেন , এর জন্য খুব কম (কোনও) ডকুমেন্টেশন নেই। আমি এটি দিয়ে চেষ্টা করব :)
maček

4
@ জোনাথন জুলিয়ান, আমি যদি এই বার 10 বার ভোট দিতে পারি, তবে আমি করব। কোথায় হ্যাক as_jsonডক্স! আবার ধন্যবাদ :)
maček

71

আপনার যদি রেল 3 এ সমস্যা হয় তবে এর serializable_hashপরিবর্তে ওভাররাইড করুন as_json। এটি আপনার এক্সএমএল ফর্ম্যাটিংটিও বিনামূল্যে পাবেন :)

এটি আমাকে চিরকালের জন্য খুঁজে বের করতে লাগল। আশা করি যে কাউকে সাহায্য করবে


4
পদ্ধতি সম্পর্কে কোনও ভাল লেখার বিষয়ে কেউ কি জানেন serializable_hash? আমি যখন এটি ব্যবহার করি, তখন এটি আমার পরবর্তী xML আউটপুটটির নাম (যেমন "একটি উদ্ধৃতি" কোট অবজেক্টের জন্য ") মুড়ে ফেলার পরিবর্তে সর্বদা এটি" <hash> "দিয়ে
টাইলার কলিয়ার

@ টাইলারক্লিয়লার এটির মতো বিকল্পগুলি হওয়া উচিতto_xml
স্যাম সোফেস

এই সমাধানের জন্য ধন্যবাদ! আমি রুবি 2 / রেল 4 ব্যবহার করছি এবং আস_জেসন নেস্টেড বস্তুগুলির সাথে কাজ করছিল না, ওভাররাইড পদ্ধতিতে 'অন্তর্ভুক্ত' বলা হয়নি, সিরিয়ালাইজযোগ্য_হ্যাশ দিয়ে এটি কাজ করে!
সানটাকাস

পরিবর্তে সিরিয়ালাইজযোগ্য_হ্যাশ কেন ওভারড্রেন করা উচিত তার ব্যাখ্যার জন্য রোবট.থচটবট.com/better-serialization- less-as-json দেখুন ।
টোফার হান্ট

36

এমন লোকদের জন্য যারা ব্যবহারকারীদের বিকল্পগুলি উপেক্ষা করতে চান না তবে তাদের এরগুলি যুক্ত করতে চান:

def as_json(options)
  # this example DOES NOT ignore the user's options
  super({:only => [:email, :handle]}.merge(options))
end

আশা করি এটি যে কাউকে সহায়তা করবে :)


4
options= {}
এইভাবেই

4

টু_জসনকে নয়, তবে_জসনকে ওভাররাইড করুন। এবং আস_জসন থেকে আপনি যা চান তা কল করুন:

এটা চেষ্টা কর:

def as_json 
 { :username => username, :foo => foo, :bar => bar }
end

নয় as_jsonশুধু ActiveResource জন্য?
জোনাথন জুলিয়ান

আপাতদৃষ্টিতে অ্যাক্টিভেকর্ড :: সিরিয়ালায়নে as_json api.rubyonrails.org/class/ActiveRecord/Sialization.html
glebm

@glebm, আমি এটি চেষ্টা করেছিলাম এবং আমি একই ফলাফল পাচ্ছি। আমি আপনাকে দেখাতে আমার প্রশ্ন আপডেট করেছি।
maček

@glebm, আমি এখনও ঠিক একই ত্রুটি পেয়ে যাচ্ছি। এমনকি আমি যখন render :json => current_userপ্রত্যাশিত ডিফল্ট ফলাফল পাই ( UserJSON ফর্ম্যাটে মডেলের সমস্ত বৈশিষ্ট্য )। আমি যখন as_jsonআমার Userমডেলটিতে এই পদ্ধতিটি যুক্ত করি এবং একই জিনিসটি চেষ্টা করি, তখন আমি ত্রুটিটি
পেয়েছি

@ বিগ বিএম, আপনাকে ধন্যবাদ আমি জানি আমি কিছু ভুল করছি। এটি আপডেট হওয়া প্রশ্নটি পরীক্ষা করার মতো হতে পারে।
maček
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.