रूबी ऑन रेल्स: डिलीट मल्टीपल हैश कीज


148

मैं अक्सर खुद को यह लिखते हुए पाता हूं:

params.delete(:controller)  
params.delete(:action)  
params.delete(:other_key)  
redirect_to my_path(params)  

हटाने का निशान सही नहीं लगता है और न ही:

[:controller, :action, :other_key].each do |k|
  params.delete(k)
end

क्या कुछ सरल और साफ है?


जब मैंने लिखा कि दूसरा दृष्टिकोण सही नहीं लगा, तो मेरा मतलब था कि हाश एपीआई की समृद्धि को देखते हुए, मुझे संदेह था कि इसके लिए पहले से ही कुछ विधि या मुहावरा था और एक बंदर पैच आवश्यक नहीं होगा। शायद नहीं, हालांकि। सभी ने उत्तर देने के लिए बहुत धन्यवाद!
मार्क वेस्टलिंग

3
हैश # को छोड़कर बिल्कुल वही था जिसकी मुझे तलाश थी। मुझे याद नहीं था कि यह एक रेल कोर एक्सटेंशन है, इसलिए जब मुझे हैश एपीआई में नहीं मिला तो मैं हैरान रह गया।
मार्क वेस्टलिंग

1
ध्यान दें कि सख्ती से उत्तर है, Hash#except!लेकिन Hash#exceptजाने के लिए रास्ता है (गड़बड़ मत करो params!)। अंगूठे के एक नियम के रूप में, किसी भी वस्तु के साथ गड़बड़ न करें जब तक कि पूरी तरह से आवश्यक न हो, साइड-इफेक्ट के अप्रत्याशित परिणाम हो सकते हैं।
tokland

जवाबों:


219

मैं अनुमान लगा रहा हूँ कि आप हैश से अनजान हैं # विधि को छोड़कर ActiveSupport हैश में जुड़ जाता है।

यह आपके कोड को सरल बनाने की अनुमति देगा:

redirect_to my_path(params.except(:controller, :action, :other_key))

इसके अलावा, आप बंदर पैच नहीं होगा, क्योंकि रेल टीम ने आपके लिए किया था!


1
आह, मुझे पता था कि मैंने इसे पहले देखा था, लेकिन मुझे याद नहीं था कि मैं कहाँ था! (इसलिए मेरा "यह सही नहीं लगता है" टिप्पणी।) धन्यवाद!
मार्क वेस्टलिंग

3
उन कम प्रलेखित विधियों में से एक। मैं एक उत्तर का प्रस्ताव करते हुए कुछ इस तरह की तलाश में गया था, लेकिन इसे नहीं देखा।
tadman

1
किसी कारण के अलावा काम नहीं किया। लेकिन except!किया। रेल्स 3.0
ट्रिप

4
ActiveRecord विशेषताओं पर रेल 3.2, कुंजी के लिए तार का उपयोग करना था? यानी User.attributes.except("id", "created_at", "updated_at")प्रतीकों ने काम नहीं किया
9

1
@ हाउस 9 का उल्लेख करते हुए, ActiveRecord attributesविधि Hashउन कुंजियों के साथ देता है जो हैं String। तो फिर आपको स्ट्रिंग कुंजी नामों का उपयोग करना होगा .except()। हालाँकि मैं इसे Hash.symbolize_keysएक ला का उपयोग कर के आसपास प्राप्त करता हूं @user.attributes.symbolize_keys.except(:password, :notes)- इसका उपयोग करने symbolize_keysसे यह काम होता है क्योंकि एक उम्मीद होगी
फायरड्रैगन

44

Hash#exceptअपनी समस्या को हैंडल करते समय , ध्यान रखें कि यह संभावित सुरक्षा समस्याओं का परिचय देता है । आगंतुकों के किसी भी डेटा को संभालने के लिए अंगूठे का एक अच्छा नियम एक श्वेतसूची दृष्टिकोण का उपयोग करना है। इस मामले में, Hash#sliceबजाय का उपयोग कर ।

params.slice!(:param_to_remove_1, :param_to_remove_2)
redirect_to my_path(params)

1
पुनर्निर्देशन के आसपास के सुरक्षा मुद्दों का उल्लेख करने के लिए धन्यवाद।
डेविड जे।

12
बस एक सिर: ActiveSupport, रूबी ही नहीं, हैश # स्लाइस और # स्लाइस प्रदान करता है! as.rubyonrails.org/classes/ActiveSupport/CoreExtensions/Hash/…
डेविड जे।

1
मुझे काम करने के लिए डेविड जेम्स का लिंक नहीं मिला, लेकिन यह ठीक प्रतीत होता है: api.rubyonrails.org/classes/Hash.html#method-i-slice
डोमिनिक सियर्स

अपरिभाषित विधि 'टुकड़ा!' के लिए{:b=>2, :c=>3}:Hash
खुर्रम रज़ा

25

आपके द्वारा मूल रूप से आपके प्रश्न में पोस्ट किए गए कोड से मैं पूरी तरह से खुश हूँ।

[:controller, :action, :other_key].each { |k| params.delete(k) }

Hashइसे संशोधित किए बिना सबसे अच्छा उत्तर है: +1:
डैन ब्रैडबरी

मैंने इस पद्धति का उपयोग किया है, लेकिन हैश के नाम के साथ पारम्स को बदल दिया और फिर यह काम किया !! हैश म्यूट हो जाता है।
पाब्लो


8

एक बंदर पैच आग?

class Hash
  def delete_keys!(*keys)
    keys.flatten.each do |k|
      delete(k)
    end

    self
  end

  def delete_keys(*keys)
    _dup = dup
    keys.flatten.each do |k|
      _dup.delete(k)
    end

    _dup
  end
end

5
बंदर पैच अंतिम उपाय का एक उपकरण है।
बॉब अमन

15
मौजूदा कार्यों को बदलने वाले बंदर पैच अंतिम उपाय का एक उपकरण है। नए कार्यों को जोड़ने वाले बंदर पैच रूबी 101 हैं।
डेविड सीलर

4
delete(k)इसके बजाय होना चाहिएdelete(key)
विंसेंट

कोड रखरखाव के लिए गैर-विनाशकारी का कार्यान्वयन delete_keysबस होना चाहिएdup.delete_keys!(*keys)
Phrogz

@Phrogz दूसरे के संदर्भ में एक को परिभाषित करना हमेशा एक बुरा विचार नहीं है, लेकिन यह सिर्फ स्पष्टता के लिए यहां अनियंत्रित छोड़ दिया गया है।
tadman

2

मुझे नहीं पता कि आपके प्रस्तावित समाधान में आपको क्या गलत लगता है। मुझे लगता है कि आप delete_allहैश या कुछ पर एक विधि चाहते हैं ? यदि हां, तो टैडमैन का जवाब समाधान प्रदान करता है। लेकिन स्पष्ट रूप से, एक-बंद के लिए, मुझे लगता है कि आपके समाधान का पालन करना बेहद आसान है। यदि आप इसका अक्सर उपयोग कर रहे हैं, तो आप इसे एक सहायक विधि में लपेटना चाह सकते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.