2011-01-20 12 views
25

प्रस्तावना:रेल 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 एक हैश को जेसन स्ट्रिंग में बदल देगा।

मैंने वर्तमान में उपयोग किए जाने वाले कोड के लिए नीचे दिया गया कोड अपडेट किया है, इसलिए मूल प्रश्न समझ में नहीं आता है। अगर कोई मूल प्रश्न और कोड को एक प्रतिक्रिया में कोड और निश्चित कोड के रूप में दिखाता है तो मैं इसके बजाय ऐसा कर सकता हूं।

+0

आपके पास कोई प्रश्न है? मुझे समझ में नहीं आता ... – Anton

+10

मुझे इस पोस्ट में सवाल ढूंढना मुश्किल हो गया, लेकिन मुझे अंत में यह पता चला। हालांकि, अगर आप अपने आप पर एक समाधान पर पहुंचे हैं तो प्रश्न को अद्यतन करने के बजाय कृपया उत्तर के रूप में उत्तर दें (और स्वीकृत के रूप में चिह्नित करें)। – Kev

+0

@jay, मैं कहूंगा कि आपको भविष्य में अपनी पोस्ट संपादित करने के बारे में और अधिक सावधान रहने की आवश्यकता है - आपके प्रश्न पर पहुंचने पर एक आगंतुक को अब "अपडेट: एक और समाधान मिला ..." जो बहुत भ्रमित है। – Ben

उत्तर

0

जवाब के लिए: एक विधि को लागू करने के

  • बंदर-पैच सरणी कि: सवाल :-)

    संक्षेप में देखते हैं, वहाँ अलग अलग समाधान एक ऊपर सवाल में है, जिनमें से कर रहे हैं, (पुराना) v1 JSON वापस

+0

हाँ, यह मेरा SO n00bness बाहर आ रहा था। उम्मीद है कि संपादन की मदद से यह अधिक स्पष्ट है ... – jay

0

मैंने इस सामग्री प्रकार की चाल को रेल परियोजना में कहीं भी इस्तेमाल नहीं किया है, इसलिए यह मेरे लिए नया है। जिस तरह से मैंने इसे देखा है, वह रूट नेमस्पेस (उदा।/एपीआई/वी 1 /) को परिभाषित करना है जो एक नियंत्रक (कहें, एपी :: संस्करण 1 नियंत्रक) पर जाता है।

इसके अलावा, मुझे पता है कि आप चीजें "रेल मार्ग" करना चाहते हैं, और हो सकता है कि यह 1.3 से रेल के साथ एक लड़के से क्रोटचेटी आ रहा है, लेकिन पूरे respond_with/respond_to सामान मेरे लिए जादू है। मुझे नहीं पता था कि respond_to ऑब्जेक्ट्स को क्रमबद्ध करते समय to_XXX विधि की तलाश करता है, उदाहरण के लिए (शायद मुझे उस पर पढ़ने की आवश्यकता है)। बंदर-पैच होने के कारण उस तरह ऐरे मूर्खतापूर्ण लगता है। इसके अलावा, एक एपीआई के लिए, मॉडल डेटा स्वरूपण वास्तव में दृश्य का काम है, न कि मॉडल का। मैं इस मामले में rabl जैसे कुछ देख सकता हूं। here के बारे में एक अच्छा लेखन है।

+0

मैंने जांच करते समय रूट नेमस्पेस और सामग्री प्रकार का उपयोग करके दोनों को देखा। सामग्री-प्रकार विनिर्देशक अधिक "रीस्टफुल" लगता है कि संसाधन को हमेशा एक यूरी/2/jidson/1.json और /widget/1.xml होने के बजाय/a/as/widget/1 के रूप में परिभाषित किया जाता है। मैं पूरी तरह से इस बिंदु से सहमत हूं कि दृश्य प्रतिनिधित्व कर रहा है, और रैबल भी बहुत दिलचस्प लग रहा है, यह इंगित करने के लिए धन्यवाद! – jay