2010-03-23 46 views
10

我試圖淨化一個涉及用戶輸入的字符串,而不必訴諸手動製作我自己的可能的越野車正則表達式,但是,如果這是唯一的方式,我也將不勝感激,如果任何人都可以點我在正確的方向到一個不太可能缺少任何東西的正則表達式。 Rails中有許多方法可以讓你輸入原生的SQL命令,人們如何逃避用戶對這些命令的輸入?Ruby on Rails:如何在不使用find時清理SQL字符串?

我問的問題是一個寬泛的問題,但在我的特殊情況下,我正在使用Postgres數據庫中的一列,Rails本身並不理解,據我所知,tsvector只能保存純文本文本搜索信息。 Rails能夠像它是一個字符串一樣編寫和讀取它,但是,與字符串不同,當我在模型中執行vector =之類的東西時,它似乎不會自動轉義它。

例如,當我做model.name ='::',其中name是一個字符串,它工作正常。當我做model.vector =「::」是錯誤的:

ActiveRecord::StatementInvalid: PGError: ERROR: syntax error in tsvector: "::" 
"vectors" = E'::' WHERE "id" = 1 

這似乎是缺乏所引起的分號逃避的問題,我可以手動設置矢量=「::」精。

我也有好主意,也許我可以叫類似:

ActiveRecord::Base.connection.execute "UPDATE medias SET vectors = ? WHERE id = 1", "::" 

然而,這個語法是不行的,因爲原始的SQL命令沒有訪問找到的逃避方法並通過使用?輸入字符串。標記。

這引起了我與使用任何類型的用戶輸入調用connection.execute一樣的問題,因爲它歸結爲清理字符串,但我似乎無法找到任何手動調用Rails的SQL字符串消毒方法。任何人都可以提供建議嗎?

回答

14

此方法添加到您的模型:

class Media < ActiveRecord::Base 
    def self.execute_sql(*sql_array)  
    connection.execute(send(:sanitize_sql_array, sql_array)) 
    end 
end 

現在可以執行任意SQL如:

Media.execute_sql('UPDATE medias SET vectors = ? WHERE id = 1', '::') 

參考

1)sanitize_sql_array

+1

謝謝你的提示,就像你說的那樣工作。然而,不幸的是,Rails似乎並沒有爲SQL實際清理冒號(:),而且我仍然在該行上發生錯誤。也許需要冒號衛生是tsvectors獨有的。看起來我將不得不走到吱吱作響的正則表達式路線。 – 2010-03-23 14:06:05