Ruby on rails Ruby UTF8编码问题

Ruby on rails Ruby UTF8编码问题,ruby-on-rails,ruby,postgresql,encoding,Ruby On Rails,Ruby,Postgresql,Encoding,我有一个Ruby/Rails应用程序 我的postgresql数据库中有一个artists表,我想按名称查询它。我有一些艺术家与葡萄牙语字符等,我有一些问题质疑他们 例如,一个乐队被称为Legião Urbana。如果我从我的应用程序中使用字符串“legiã”进行查询,我会得到以下参数: {"action"=>"search_artist", "q"=>"legi\343", "controller"=>"home"} 但是,我从查询中得到一个错误 Artist.all(:c

我有一个Ruby/Rails应用程序

我的postgresql数据库中有一个artists表,我想按名称查询它。我有一些艺术家与葡萄牙语字符等,我有一些问题质疑他们

例如,一个乐队被称为Legião Urbana。如果我从我的应用程序中使用字符串“legiã”进行查询,我会得到以下参数:

{"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或以某种方式修复这种情况?

您需要知道查询字符串中该参数的编码是什么

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片段都是安全的应该不会有任何问题。

我认为这可能会解决问题

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

好的,我更感兴趣的是编码/转换。如何找到参数的编码?我知道SQL注入问题,但我只想给出一个查询示例。+1表示“您需要将参数作为SQL参数传递,而不是使用字符串插值”。不幸的是,我不太熟悉1.8字符串编码情况。我确实知道,在1.8中处理编码问题是相当困难的,如果您面临编码问题,最好的办法是转到1.9。