Ruby UTF8编码问题

joh*_*ire 2 ruby postgresql encoding ruby-on-rails

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

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

例如,一支乐队名为LegiãoUrbana.如果我从我的应用程序查询字符串"legiã",我得到以下参数:

{"action"=>"search_artist", "q"=>"legi\343", "controller"=>"home"}
Run Code Online (Sandbox Code Playgroud)

但是我从查询中收到错误

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

PGError: ERROR:  invalid byte sequence for encoding "UTF8": 0xe32527
Run Code Online (Sandbox Code Playgroud)

我应该怎么做才能转换成UTF8或以某种方式解决这个问题?

yfe*_*lum 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
Run Code Online (Sandbox Code Playgroud)

然后,您需要在执行字符串插值(#{...}语法)之前将参数从该编码转换为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]}")
Run Code Online (Sandbox Code Playgroud)

SQL注入是当你在建立正确的SQL碎片作一些输入字符串的方式做字符串插值和编码字符串时出现的安全问题,但不是为别人.在语言/框架,其中的参数是比较困难的工作,这是可以接受的做字符串插值或字符串建设(如果它仍然是很容易做到的字符串插值或字符串建设),只要你的研究详尽如何无论输入字符串如何,都需要对插值字符串进行编码以构建正确的SQL片段.由于SQL注入是很容易通过订购或命名参数(见上面的四个样本),以避免使用Rails,你不应该确保你的SQL片段都是安全的任何问题.