2010-12-02 107 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