5

मुझे प्रश्न चिह्न का उपयोग करने के बीच अंतर के दौरान थोड़ी देर के लिए परेशान किया गया है, उदा।उपयोग के बीच क्या अंतर है? और% जब ActiveRecord में फ़ील्ड को sanitizing?

Foo.find(:all, :conditions => ['bar IN (?)', @dangerous]) 

और स्पिंटफ़ शैली फ़ील्ड प्रकारों का उपयोग करना, उदा।

Bar.find(:all, :conditions => ['qux IN (%s)', @dangerous]) 

संवेदीकरण इनपुट में। क्या कोई सुरक्षा लाभ है, अगर आपको पता है कि आप एक आईडी की तरह हैं - एक आईडी की तरह - और एक स्ट्रिंग नहीं,% d ओवर का उपयोग करने में?, या आप बस एक बड़ी गलती त्रुटि मांग रहे हैं जब एक स्ट्रिंग इसके साथ आती है ?

क्या यह नया बदलता है। रेल 3 और 4 में कहीं वाक्यविन्यास?

+0

मुझे यह भी पता नहीं था कि यह रेल 2 – phoet

+1

@muistooshort में संभव है, ऐसा लगता है कि यह कम से कम रेल में काम करता है 3. भविष्य के सबूत के बारे में अच्छा बिंदु क्योंकि यह कहीं भी दस्तावेज प्रतीत नहीं होता है। –

+0

3+ में मैं कहूंगा कि 'कहां (: bar => @ खतरनाक)' वैसे भी, अगर सही है तो 'सही' होगा '@ खतरनाक' एक गैर-खाली सरणी है (लेकिन हां, [कुछ बेवकूफ] (http://stackoverflow.com/a/12946338/479863) यदि यह एक खाली सरणी है)। –

उत्तर

1

%s तारों के लिए है। मुख्य अंतर यह है कि %s उद्धरण जोड़ें नहीं। ActiveRecord::QueryMethods.where से:

Lastly, you can use sprintf-style % escapes in the template. This works slightly differently than the previous methods; you are responsible for ensuring that the values in the template are properly quoted. The values are passed to the connector for quoting, but the caller is responsible for ensuring they are enclosed in quotes in the resulting SQL. After quoting, the values are inserted using the same escapes as the Ruby core method Kernel::sprintf .

उदाहरण:

User.where(["name = ? and email = ?", "Joe", "[email protected]"]) 
# SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]'; 

User.where(["name = '%s' and email = '%s'", "Joe", "[email protected]"]) 
# SELECT * FROM users WHERE name = 'Joe' AND email = '[email protected]'; 

अद्यतन:

आप एक सरणी से गुजर रहे हैं। %s तो यह काम करता है की उम्मीद नहीं कर सकते हैं के रूप में तर्क पर कॉल .to_s लगता है:

User.where("name IN (%s)", ["foo", "bar"]) 
# SELECT * FROM users WHERE (name IN ([\"foo\", \"bar\"])) 

User.where("name IN (?)", ["foo", "bar"]) 
# SELECT * FROM users WHERE (name IN ('foo','bar')) 

सरल प्रश्नों के लिए आप हैश संकेतन का उपयोग कर सकते हैं:

User.where(name: ["foo", "bar"]) 
# SELECT * FROM users WHERE name IN ('foo', 'bar') 
+0

यह सिर्फ उद्धरण के बारे में नहीं है।% s जो भी आप फेंकते हैं उस स्ट्रिंग में कनवर्ट करना प्रतीत होता है और परिणाम क्वेरी में जैसा होता है। नहीं नहीं। कृपया मेरा जवाब भी देखें। – Giuseppe

+0

@ जिएसेपे आप सही हैं, मैंने अनदेखा किया है कि ओपी एक सरणी को '% s' तक पास करता है। – Stefan

+0

मुझे लगता है कि यहां मुख्य टेकवे यह है कि '% s' ** ** उद्धरण नहीं देता है और इसलिए स्वच्छता के लिए वास्तव में बहुत उपयोगी नहीं है। हालांकि, यह बच निकलता है, इसलिए यह बेकार नहीं है। 'खतरनाक 'जरूरी नहीं है कि वह एक सरणी हो। यह अल्पविराम से अलग मूल्यों की स्ट्रिंग हो सकती है, उदा। '@ खतरनाक =" 1, 2, 3 "' –

1

जहां तक ​​मेरा बता सकते हैं, %s बस आवेषण आपकी क्वेरी में जो भी @dangerous.to_s होता है, और आप इसके लिए ज़िम्मेदार हैं।

@dangerous = [1,2,3] 
User.where("id IN (%s)", @dangerous) 

निम्नलिखित गलत वाक्यविन्यास में परिणाम होगा:

SELECT `users`.* FROM `users` WHERE (id IN ([1, 2, 3])) 

जबकि:

उदाहरण के लिए, यदि @dangerous पूर्णांकों की एक सरणी है, तो आप एक SQL त्रुटि प्राप्त होगी

User.where("id IN (?)", @dangerous) 

सही क्वेरी उत्पन्न करता है:

SELECT `users`.* FROM `users` WHERE (id IN (1,2,3)) 

इस प्रकार, है मुझे लगता है कि जब तक आप बहुत, बहुत अच्छी तरह से तुम क्या कर रहे पता है, तुम, ? ऑपरेटर अपना काम करने देना चाहिए खासकर यदि आप के रूप में सुरक्षित @dangerous की सामग्री पर भरोसा नहीं करते।

+0

ऐसा लगता है कि '% s' बचता है, इसलिए यह" सुरक्षित "है, लेकिन क्योंकि यह उद्धरण नहीं देता है, इसमें त्रुटियों सहित अप्रत्याशित परिणाम हो सकते हैं। आप सही हैं, शायद इससे बचने के लिए सबसे अच्छा है जब तक कि ऐसा करने का कोई अच्छा कारण न हो। 'Foo.where ("bar =?", @ Danger.to_s)' वही काम पूरा करेगा, लेकिन सही ढंग से उद्धरण के बारे में कम चिंता के साथ। लेकिन यहां तक ​​कि यह शायद अनावश्यक है और शायद अधिकांश समय भी अवांछनीय है। –

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