2011-12-14 18 views
8

मान लीजिए आप एक यूआरएलरेल: क्वेरी पैरामीटर बनाम पोस्ट पैरामीटर

localhost:3000?a=1 

और अनुरोध में है, तो आप भी एक पोस्ट पैरामीटर

a=2 

क्या

params[:a] इस में हो जाएगा मामला? क्या यह HTTP क्रिया पर निर्भर करता है?

यह HTTP क्रिया पर निर्भर करता है,

क्या आपके प्रपत्र

<form method='post' action='/?a=2'> 
    <input type='hidden' name='a' value='3'/> 
</form> 

क्या params[:a] इस मामले में हो सकता है की तरह लग रहा है?

अद्यतन

तो मैं सिर्फ एक छोटा सा प्रयोग किया था और क्रोम डिबगर इस्तेमाल किया ?authenticity_token=abc कार्रवाई url संलग्न करने के लिए। मैंने सर्वर लॉग को देखा और मैंने देखा कि पैरामीटर authenticity_token => 'abc' है। मुझे यह भी विश्वास है कि इस मामले में विधि POST है।

मुझे बताएं कि आप किसके साथ आए थे।

उत्तर

18

जब मैंने नमूना कोड में यह कोशिश की, तो मैं क्या देख पा रहा था कि क्वेरी पैरामीटर (जीईटी) को पोस्ट बॉडी से प्राथमिकता दी गई है। इसलिए, मैं Rack के कोड में खोद गया जो रेल में HTTP अनुरोधों को संभालता है।यहाँ request.rb

# Returns the data recieved in the query string. 
def GET 
    .... 
end 

# Returns the data recieved in the request body. 
# 
# This method support both application/x-www-form-urlencoded and 
# multipart/form-data. 
def POST 
    .... 
end 

# The union of GET and POST data. 
def params 
    @params ||= self.GET.merge(self.POST) 
rescue EOFError 
    self.GET 
end 

यहाँ, विधि से कोड है

  • प्राप्त करें - एक हैश प्रारूप में क्वेरी पैरामीटर रिटर्न
  • पोस्ट - एक हैश प्रारूप में पोस्ट शरीर रिटर्न

तो, params के कोड के अनुसार, GET पैरामीटर को समान कुंजी के मामले में POST पैरामीटर द्वारा ओवरराइड किया जाना चाहिए। (self.GET.merge(self.POST))। लेकिन, जब मैंने व्यावहारिक रूप से कोशिश की तो मुझे यह मिला कि इसके विपरीत क्या है।

तो, एकमात्र मौका यह है कि इस कोड को रेल द्वारा ओवरराइड किया जा रहा है। जब मैंने इसके बारे में सोचा, तो यह सही समझ में आया क्योंकि रेल से params हैश में हमेशा "controller" और "action" कुंजी शामिल होंगी, जो रैक के मामले में अनुपस्थित होंगी। इसलिए, मैंने रेल के कोड को भी देखा, और पाया कि params विधि वास्तव में ओवरराइड की जा रही थी। रेल स्रोत कोड में request.rb और parameters.rb पर एक नज़र डालें। parameters.rb में, हमने:

# Returns both GET and POST \parameters in a single hash. 
    def parameters 
    @env["action_dispatch.request.parameters"] ||= begin 
     params = request_parameters.merge(query_parameters) 
     params.merge!(path_parameters) 
     encode_params(params).with_indifferent_access 
    end 
    end 
    alias :params :parameters 

और request.rb में:

# Override Rack's GET method to support indifferent access 
def GET 
    @env["action_dispatch.request.query_parameters"] ||= (normalize_parameters(super) || {}) 
end 
alias :query_parameters :GET 

# Override Rack's POST method to support indifferent access 
def POST 
    @env["action_dispatch.request.request_parameters"] ||= (normalize_parameters(super) || {}) 
end 
alias :request_parameters :POST 

तो, यहाँ

  • query_parameters - POST पद्धति के लिए अन्य नाम - GET विधि
  • REQUEST_PARAMETERS के लिए उर्फ
  • path_parameters - विधि जो ret ret params के लिए उर्फ ​​(यहां यह ओवरराइड की गई थी)

नोट मिलता है विधि और POST पद्धति भी अधिरोहित किए गए थे, मुख्य रूप से हैश एक को लौट कन्वर्ट करने के लिए - नियंत्रक और कार्रवाई एक हैश

  • पैरामीटर के रूप में अनुरोध के लिए urns हैशविथ इंडिफरेंस एक्सेस का ऑब्जेक्ट।

    तो, यहां कोड को देखकर (params = request_parameters.merge(query_parameters)), यह स्पष्ट हो जाता है कि पोस्ट पैरामीटर रेल में समान कुंजी के मामले में जीईटी पैरामीटर द्वारा ओवरराइड किए जाते हैं। या दूसरे शब्दों में, पोस्ट पैरामीटर पर जीईटी पैरामीटर प्राथमिकता दी जाती है।

  • +0

    जासूस काम के लिए बहुत बहुत धन्यवाद! – cofiem

    +1

    जोड़ा गया नोट कि आप नियंत्रक विधि में 'ActionDispatch :: Request' ऑब्जेक्ट तक पहुंच प्राप्त कर सकते हैं: किसी भी नियंत्रक विधि से 'request.query_parameters' और' request.request_parameters' आपको टाइप करके अलग-अलग पैरा प्राप्त करेंगे। – keaplogik

    +0

    @keaplogik जो निश्चित रूप से ध्यान देने योग्य है। – rubyprince

    1

    यह 2 होगा। लेकिन रूटिंग के लिए, यह '1' के खिलाफ मिल जाएगा।

    यदि आप चाहते हैं, तो आप प्राप्त करें और पोस्ट करें। पोस्ट प्राप्त करने के लिए request.GET और request.POST का उपयोग कर सकते हैं।

    1

    नहीं, यह HTTP क्रिया पर निर्भर नहीं है लेकिन आप निश्चित रूप से GET और POST को संभालने के लिए अलग-अलग कार्रवाइयां कर सकते हैं या यह वही हो सकता है और आपको दोनों मामलों में 'पैराम्स': ए] मिल जाएगा। HTTP अनुरोधों के लिए

    +0

    मैंने शायद अपना प्रश्न खराब लिखा होगा लेकिन मेरे प्रश्न यह है कि यदि एक ही कुंजी के साथ पोस्ट परम और क्वेरी param है और इसे POST विधि के माध्यम से अनुरोध किया जाता है। किस पर प्राथमिकता लेनी चाहिए? – denniss

    +0

    बस एक परीक्षण किया गया और इनपुट मूल्य को अनदेखा कर दिया गया, फिर 'फॉर्म' टैग में से एक को प्राथमिकता मिलती है। –

    +0

    कमाल धन्यवाद! मुझे वही चीज़ मिल गई है =) – denniss

    6

    रेल usesRack::Request। हालांकि, यह (एक उपनाम के माध्यम से) Rackparams विधि को फिर से परिभाषित करता है।

    # Returns both GET and POST \parameters in a single hash. 
        def parameters 
        @env["action_dispatch.request.parameters"] ||= begin 
         params = request_parameters.merge(query_parameters) 
         params.merge!(path_parameters) 
         encode_params(params).with_indifferent_access 
        end 
        end 
        alias :params :parameters 
    

    नोट aliased parameters विधि:

    यह params विधि है, जो अनुरोध पैरामीटर देता है, के रूप में कार्यान्वित किया जाता है।

    फिर से परिभाषित किए बिना, क्वेरी स्ट्रिंग के पैरामीटर पोस्ट बॉडी से पैरामीटर ओवरराइट करेंगे।

    +0

    तो क्या आप समझा सकते हैं कि मेरे प्रयोग ने मुझे यह परिणाम क्यों दिया? यह ** अपडेट ** – denniss

    +0

    के तहत है, मुझे कोड का एक महत्वपूर्ण टुकड़ा याद आया। ActionDispatch :: अनुरोध में ActionDispatch :: Http :: पैरामीटर शामिल हैं, जो पैराम्स को फिर से परिभाषित करता है। मेरा जवाब अपडेट कर रहा है। – toddsundsted

    +0

    @toddsundsted .. + 1..तुमने मुझे जवाब के अपडेट में भी हराया :) – rubyprince

    संबंधित मुद्दे