प्रस्तावना:रेल 3 प्रतिक्रिया स्वरूप और संस्करण स्वीकार करें शीर्षक में विक्रेता MIME प्रकार का उपयोग कर
मैं कैसे संस्करण एक API के लिए जांच की और यह करने के लिए कई तरीके पाया। मैंने peter williams' सुझाव देने का प्रयास किया और संस्करण और प्रारूप निर्दिष्ट करने के लिए नए विक्रेता माइम प्रकार बनाए। मुझे "रेल मार्ग" के बाद ऐसा करने के लिए कोई निश्चित लेखन नहीं मिल सका, इसलिए मैंने कई स्थानों से जानकारी एकत्र की। मैं इसे काम करने में सक्षम था, लेकिन respond_with
में रेंडरर्स विजेट सरणी बनाम विजेट इंस्टेंस को संभालने के तरीके में कुछ मूर्खता है।
बुनियादी चरणों & समस्या:
मैं माइम प्रकार पंजीकृत है और दोनों एक्सएमएल और ApplicationController को json में संस्करण 1 का दाता कहा, दाता फोन मॉडल में to_myproj_v1_xml
और to_myproj_v1_json
तरीकों। respond_with(@widget)
ठीक काम करता है लेकिन respond_with(@widgets)
HTTP/1.1 500 Internal Server Error
फेंकता है कि "टेम्पलेट गुम है"।
वर्कअराउंड:
"खाका याद आ रही है" का अर्थ है कि कोई भी रेंडर कहा जाता था और कोई मिलता-जुलता टेम्पलेट मौजूद है। दुर्घटना से, मैंने पाया कि यह एक क्लास विधि की तलाश में है ... इसलिए मैं नीचे दिए गए कोड के साथ आया जो काम करता है लेकिन मैं इसके साथ वास्तव में खुश नहीं हूं। गुस्से में ज्यादातर xml = obj.to_myproj_v1_xml(obj)
और मॉडल में डुप्लिकेशन से संबंधित है।
मेरा सवाल है - क्या किसी ने थोड़ा क्लीनर फैशन में कुछ भी किया है?
- = अद्यतन कोड = -
config/initializers/mime_types.rb:
Mime::Type.register 'application/vnd.com.mydomain.myproj-v1+xml', :myproj_v1_xml
Mime::Type.register 'application/vnd.com.mydomain.myproj-v1+json', :myproj_v1_json
एप्लिकेशन/नियंत्रक/application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery
before_filter :authenticate
ActionController.add_renderer :myproj_v1_xml do |obj, options|
xml = obj.to_myproj_v1_xml
self.content_type ||= Mime::Type.lookup('application/vnd.com.mydomain.myproj-v1+xml')
self.response_body = xml
end
ActionController.add_renderer :myproj_v1_json do |obj, options|
json = obj.to_myproj_v1_json
self.content_type ||= Mime::Type.lookup('application/vnd.com.mydomain.myproj-v1+json')
self.response_body = json
end
end
ऐप/मॉडल/widget.rb:
class Widget < ActiveRecord::Base
belongs_to :user
V1_FIELDS = [:version, :model, :description, :name, :id]
def to_myproj_v1_xml
self.to_xml(:only => V1_FIELDS)
end
def to_myproj_v1_json
self.to_json(:only => V1_FIELDS)
end
def as_myproj_v1_json
self.as_json(:only => V1_FIELDS)
end
end
एप्लिकेशन/नियंत्रक/widgets_controller.rb:
class WidgetsController < ApplicationController
respond_to :myproj_v1_xml, :myproj_v1_json
def index
@widgets = @user.widgets
respond_with(@widgets)
end
def create
@widget = @user.widgets.create(params[:widget])
respond_with(@widget)
end
def destroy
@widget = @user.widgets.find(params[:id])
respond_with(@widget.destroy)
end
def show
respond_with(@widget = @user.widgets.find(params[:id]))
end
...
end
config/initializers/monkey_array.rb
class Array
def to_myproj_v1_json(options = {})
a = []
self.each { |obj| a.push obj.as_myproj_v1_json }
a.to_json()
end
def to_myproj_v1_xml(options = {})
a = []
self.each { |obj| a.push obj.as_myproj_v1_json } # yes this is json instead of xml. as_json returns a hash
a.to_xml()
end
end
अद्यतन:
एक और समाधान मिला जो बेहतर महसूस करता है लेकिन अभी भी थोड़ा अजीब है (मैं अभी भी बंदर पैच के साथ पूरी तरह से आरामदायक नहीं हूं), शायद ठीक है ... मूल रूप से कक्षा विधि to_myproj_v1_json
से प्रतिक्रिया डेटा को ऐरे पर बंदर पैच में ले जाया गया। इस तरह जब विजेट्स का ऐरे होता है, तो यह प्रत्येक विजेट पर इंस्टेंस विधि as_myproj_v1_json
पर कॉल करता है और पूरे ऐरे को वांछित प्रारूप के रूप में देता है।
एक ध्यान दें:
- as_json सिर्फ एक हैश बनाता json प्रारूप के साथ कोई संबंध नहीं है,। As_myproj_v1_json (या as_json ओवरराइड अगर आप कस्टम माइम प्रकारों का उपयोग नहीं कर रहे हैं) पर कस्टम स्वरूपण जोड़ें, तो to_json एक हैश को जेसन स्ट्रिंग में बदल देगा।
मैंने वर्तमान में उपयोग किए जाने वाले कोड के लिए नीचे दिया गया कोड अपडेट किया है, इसलिए मूल प्रश्न समझ में नहीं आता है। अगर कोई मूल प्रश्न और कोड को एक प्रतिक्रिया में कोड और निश्चित कोड के रूप में दिखाता है तो मैं इसके बजाय ऐसा कर सकता हूं।
आपके पास कोई प्रश्न है? मुझे समझ में नहीं आता ... – Anton
मुझे इस पोस्ट में सवाल ढूंढना मुश्किल हो गया, लेकिन मुझे अंत में यह पता चला। हालांकि, अगर आप अपने आप पर एक समाधान पर पहुंचे हैं तो प्रश्न को अद्यतन करने के बजाय कृपया उत्तर के रूप में उत्तर दें (और स्वीकृत के रूप में चिह्नित करें)। – Kev
@jay, मैं कहूंगा कि आपको भविष्य में अपनी पोस्ट संपादित करने के बारे में और अधिक सावधान रहने की आवश्यकता है - आपके प्रश्न पर पहुंचने पर एक आगंतुक को अब "अपडेट: एक और समाधान मिला ..." जो बहुत भ्रमित है। – Ben