2011-01-14 11 views
28

मुझे तैयार बयानों के बारे में पता है, लेकिन यदि मैं कच्चे एसक्यूएल का उपयोग कर रहा हूं, तो क्या ActiveRecord के पास मैन्युअल रूप से मूल्यों से बचने का कोई तरीका है?रेल में मूल्यों से बचने (mysql_real_escape_string() के समान)

कुछ इस तरह अच्छा होगा:

self.escape("O'Malley") # O\'Malley 

उत्तर

53

आप कर सकते हैं:

Dude.sanitize("O'Malley") 

या

Dude.connection.quote("O'Malley") 

एक ही परिणाम के साथ दोनों: => "'O''Malley'"

+3

मुझे आपके मॉडल का नाम पसंद है। 'दोस्त', आप कमाल हैं। –

+6

@NateSymer: हाँ, ठीक है, यह आपकी राय, आदमी की तरह है। – Fuser97381

+2

यदि कोई और सोच रहा है, हाँ, वे बिल्कुल वही हैं: [sanitize call connection.quote] (http://apidock.com/rails/ActiveRecord/Base/sanitize/class) – mltsy

4

भी Model.find_by_sql साथ आप अभी भी प्रपत्र जहां प्रश्न चिह्न बच गए मूल्यों के रूप में खड़ा कर सकते हैं।

सीधे शब्दों में रेल API दस्तावेज़ों से एक सरणी जहां पहला तत्व क्वेरी है गुजरती हैं और सफल होने के तत्वों मूल्यों में प्रतिस्थापित किया जा करने के लिए कर रहे हैं

उदाहरण:।

Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id, start_date]
+0

अगर मैं डाल रहा हूँ तो क्या होगा? –

+1

मैं इसे खोद सकता हूं, लेकिन वास्तव में: आप ActiveRelation/ActiveModel के बाहर क्यों डालेंगे? –

+1

मैं एक 'इंसर्ट इग्नोर' कर रहा हूं और मैं प्रदर्शन के लिए एक कथन में एकाधिक रिकॉर्ड अपडेट कर रहा हूं। –

19

आप आसानी से mysql2 उपयोग कर सकते हैं मणि यह करने के लिए:

irb(main):002:0> require 'rubygems' 
=> true 
irb(main):003:0> require 'mysql2' 
=> true 
irb(main):004:0> Mysql2::Client.escape("O'Malley") # => "O\\'Malley" 
=> "O\\'Malley" 

या यदि पहले mysql का उपयोग कर (नहीं mysql2) मणि:

012,
irb(main):002:0> require 'rubygems' 
=> true 
irb(main):003:0> require 'mysql' 
=> true 
irb(main):004:0> Mysql.escape_string("O'Malley") 
=> "O\\'Malley" 

इससे आपको कुछ भी बचने की अनुमति मिल जाएगी, फिर डीबी में डालें। आप sanitize विधि का उपयोग कर अपने रेल आवेदन में अधिकांश मॉडलों पर भी ऐसा कर सकते हैं। उदाहरण के लिए कहें कि आपके पास व्यक्ति नामक मॉडल है। तुम यह कर सकते थे।

Person.sanitize("O'Malley") 

यह चाल चलाना चाहिए।

+0

अजीब ... यह प्रचारित उत्तर था ... फिर बदला गया ... तर्क। – quest

+10

MySQL 2 मणि ​​के साथ: 'MySQL 2 :: क्लाइंट.स्केप ("O'Malley") # => "ओ \\' माली" ' – Duke

31

ActiveRecord स्रोत में एक त्वरित गोता एसक्यूएल बयान के [string, bind_variable[, bind_variable]] प्रकार sanitizing के लिए अपने विधि "sanitize_sql_array" का पता चलता है

आप इसे सीधे कह सकते हैं:

sql = ActiveRecord::Base.send(:sanitize_sql_array, ["insert into foo (bar, baz) values (?, ?), (?, ?)", 'a', 'b', 'c', 'd']) 
res = ActiveRecord::Base.connection.execute(sql) 
+2

जेसन: यह एक बेहतर समाधान है क्योंकि यह डीबी स्वतंत्र है। यदि ऐपोकू पर ऐप तैनात किया गया है, तो वर्तमान में स्वीकृत समाधान (@quest) काम नहीं करेगा। –

+7

चार साल बाद, 'sanitize_sql_array' और उसके चचेरे भाई अभी भी सार्वजनिक एपीआई का हिस्सा नहीं हैं। क्या कोई सुविधाजनक सार्वजनिक समतुल्य है? –

2

मामले किसी में @ jemminger के समाधान का एक और अधिक ठोस उदाहरण के लिए लग रही है, यहाँ यह थोक डालने के लिए है:

users_places = [] 
users_values = [] 
timestamp = Time.now.strftime('%Y-%m-%d %H:%M:%S') 
params[:users].each do |user| 
    users_places "(?,?,?,?)" 
    users_values << user[:name] << user[:punch_line] << timestamp << timestamp 
end 

bulk_insert_users_sql_arr = ["INSERT INTO users (name, punch_line, created_at, updated_at) VALUES #{users_places.join(", ")}"] + users_values 
begin 
    sql = ActiveRecord::Base.send(:sanitize_sql_array, bulk_insert_users_sql_arr) 
    ActiveRecord::Base.connection.execute(sql) 
rescue 
    "something went wrong with the bulk insert sql query" 
end 

यहाँ reference to sanitize_sql_array method in ActiveRecord::Base है, यह उत्पन्न करता है तारों में एकल उद्धरण से बचकर उचित क्वेरी स्ट्रिंग। उदाहरण के लिए पंच_लाइन "उन्हें आपको नीचे जाने न दें" बन जाएंगे "उन्हें आपको नीचे जाने दें"।

7

आप अपने स्ट्रिंग पाए जाते हैं कि जब आप समाधान @konus द्वारा पोस्ट की गई का उपयोग लपेटकर अतिरिक्त एकल उद्धरण नहीं करना चाहते हैं, तो आप ऐसा कर सकते हैं:

Dude.connection.quote_string("O'Malley") 

यह रिटर्न "O\'Malley""'O\'Malley'" के बजाय

+1

यह आपको SQL से नहीं रोकेगा इंजेक्शन। – tvdeyen

+2

@tvdeyen: क्या आप इस बात को स्पष्ट करने के इच्छुक होंगे कि उपरोक्त किस तरह से कमजोर होगा, खासकर स्वीकार किए गए उत्तर की तुलना में? आखिरकार, 'quote_string' इस्तेमाल होने वाले विशेष ActiveRecord एडाप्टर पर निर्भर होने जा रहा है। Mysql2 एडाप्टर और अमूर्त mysql एडाप्टर के लिए, 'उद्धरण' कॉलिंग मानों के लिए 'quote_string' कॉल करता है और परिणाम उद्धरण में लपेटता है। क्या आप किसी प्रकार का मल्टीबाइट इंजेक्शन या कुछ और सोच रहे हैं? धन्यवाद। – Nathan

+0

धन्यवाद @ नाथन।, यह मेरे लिए काम करता है .. –

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