কীভাবে কারাগুলিতে 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.