2010-12-02 110 views
2

我有一個Ruby/Rails應用程序。Ruby UTF8編碼問題

我有我的postgresql數據庫中的藝術家表,我想按名稱查詢。我有一些藝術家與葡萄牙字符等,並有一些問題查詢他們。

例如,一個樂隊被稱爲LegiãoUrbana。如果我查詢與我的應用程序字符串「萊吉亞」我得到以下PARAMS:

{"action"=>"search_artist", "q"=>"legi\343", "controller"=>"home"} 

不過,我從查詢得到一個錯誤

Artist.all(:conditions => "name LIKE '%#{params[:q]}%'") 

PGError: ERROR: invalid byte sequence for encoding "UTF8": 0xe32527 

我應該怎麼做才能轉換成UTF8或以某種方式解決這個問題?

回答

4

我認爲這可能做

require 'iconv' 
Iconv.conv("UTF8", "LATIN1", params[:q]) 
5

您需要知道查詢字符串中該參數的編碼是什麼。

Ruby 1.9包含對使用其編碼進行標記的字符串的支持。在Ruby 1.9,你可以:

params[:q].encoding # Rails 3 on 1.9 generally presents strings in UTF-8 
params[:q].encode('utf-8') # ask Ruby to re-encode it to UTF-8 

然後,你需要做字符串插值(#{...}語法)前的參數從編碼轉換爲UTF-8。

或者您需要將參數作爲SQL參數傳遞,而不是使用字符串插值。

當然,這提出了一個安全考慮,除非你知道如何正確編碼SQL中使用的文本,否則你應該從不做字符串插值來構建SQL字符串片段。由於帶有參數的SQL片段在Rails中很快且容易完成,因此應該使用它們。

# Rails 2 
Artist.all(:conditions => ['name like ?', "%#{params[:q]}%"]) 
Artist.all(:conditions => ['name like :q', { :q=> "%#{params[:q]}%" }]) 

# Rails 3 
Artist.where('name like ?', "%#{params[:q]}") 
Artist.where('name like :q', :q => "%#{params[:q]}") 

SQL注入是當你在建立正確的SQL碎片作一些輸入字符串的方式做字符串插值和編碼字符串時出現的安全問題,但不是爲別人。在參數更難處理的語言/框架中,可以接受字符串插值或字符串構建(如果字符串插值或字符串構建仍然很容易),只要您詳盡地研究需要對插入的字符串進行編碼以構建正確的SQL片段,而不管輸入字符串如何。由於通過有序或命名參數(請參見上面的四個示例),使用Rails很容易避免SQL注入,因此確保SQL片段都是安全的,不應該有任何問題。

+0

好,它更多的編碼/轉換,我很感興趣。你如何找到參數的編碼?我意識到SQL注入問題,但我只想給出一個查詢的例子。 – johnnymire 2010-12-02 16:37:16