2011-01-14 18 views

cevap

53

Sen yapabilirsiniz:

Dude.sanitize("O'Malley") 

veya

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

aynı sonucu ikisi: durumda biri ise => "'O''Malley'"

+3

Modelinizin adını seviyorum. Ahbap, harikasın. –

+6

@NateSymer: Evet, peki, senin fikrin gibi, adamım. – Fuser97381

+2

Başkalarının merak ettiği durumda, evet, tam olarak aynıdır: [çağrıları sanitize et link.quote] (http://apidock.com/rails/ActiveRecord/Base/sanitize/class) – mltsy

4

bile Model.find_by_sql ile.

Bunun birinci elemanın sorgu dizisi geçmek ve takip eden elemanlar olarak ikame edilmesi değerler

Örnek Raylar API belgelerine.

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

döndürür Ya ben ekliyorsam? –

+1

Kazabilirim ama gerçekten: ActiveRelation/ActiveModel'in dışına neden yerleştiriliyorsunuz? –

+1

"INSERT IGNORE" yapıyorum ve performans için tek bir bildirimde birden çok kaydı güncelliyorum. –

19

kolayca mysql2 kullanabilir taş bunun için:

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" 

Veya eğer daha önce mysql kullanarak (değil mysql2) mücevher:

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" 

Bu, istediğiniz herhangi bir şeyden kurtulmanızı ve daha sonra db'ye eklemenizi sağlar. Bunu da sanitize yöntemini kullanarak ray uygulamanızda çoğu modelde yapabilirsiniz. Örneğin, Kişi adında bir modeliniz olduğunu varsayalım. Yapabilirsin.

Person.sanitize("O'Malley") 

Bu hile yapmalıdır.

+0

Garip ... bu terfi cevaptı ... sonra değişti ... arg. – quest

+10

Mysql2 gem ile: 'Mysql2 :: Client.escape (" O'Malley ") # =>" O \\ 'Malley "' – Duke

31

ActiveRecord kaynağına hızlı bir dalış sql deyimi [string, bind_variable[, bind_variable]] türünü sterilize yönelik yöntem "sanitize_sql_array" ortaya koymaktadır

doğrudan diyebiliriz:

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

Jason: DB bağımsız olduğundan daha iyi bir çözüm. Uygulama Heroku üzerinde konuşlandırılmışsa, şu anda kabul edilen çözüm (@quest) çalışmayacaktır. –

+7

Dört yıl sonra, "sanitize_sql_array" ve kuzenleri hala genel API'nin bir parçası değildir. Uygun bir kamu muadili var mı? –

2

@ jemminger çözümünü uygun daha somut örnek arıyor, işte burada toplu ekleme içindir: Burada

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, bu üretir Dizelerdeki tek tırnaklardan kaçarak uygun sorgu dizesi. Örneğin, "Seni aşağı indirmelerine izin verme" adlı punch_line "Seni bırakmalarına izin verme." Eğer @konus tarafından gönderildi çözümü kullandığınızda oluşabilecek sizin dize sarma ekstra tek tırnak istemiyorsanız

7

, bunu yapabilirsiniz:

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

Bu "O\'Malley" yerine "'O\'Malley'" ait

+1

Bu sizi SQL'den korumaz enjeksiyon. – tvdeyen

+2

@tvdeyen: Özellikle kabul edilen cevapla karşılaştırıldığında, yukarıdakilerin ne şekilde savunmasız olacağını açıklamak ister misiniz? Sonuçta, 'quote_string', kullanılan ActiveRecord adaptörüne bağlı olacaktır. Mysql2 bağdaştırıcısı ve soyut mysql bağdaştırıcısı için "quote", string değerleri için quote_string işlevini çağırır ve sonucu tırnak içine alır. Bir çeşit multibyte enjeksiyon mu yoksa başka bir şey mi düşünüyorsunuz? Teşekkür ederim. – Nathan

+0

Teşekkürler @Nathan., Benim için çalışıyor .. –