Ruby UTF8编码问题

时间:2010-12-02 15:52:29

标签: ruby-on-rails ruby postgresql encoding

我有一个Ruby / Rails应用程序。

我在postgresql数据库中有一个艺术家表,我想按名称查询。我有一些艺术家有葡萄牙角色等等,我有一些问题询问他们。

例如,一支乐队名为LegiãoUrbana。如果我从我的应用程序中查询字符串“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或以某种方式解决这个问题?

2 个答案:

答案 0 :(得分: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片段都是安全的。

答案 1 :(得分:4)

我认为这可能会这样做

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