Rails + Ruby 1.9 “invalid byte squence in US-ASCII”

淺唱寂寞╮ 提交于 2020-01-13 19:10:31

问题


After upgrading to ruby 1.9 we began to notice pages failing to render from the rails template renderer when a user used a non-ASCII character. Specifically "é". I was able to resolve this issue on one of our staging servers, but I have not been able to reproduce the fix on our production server.

The fix that seemed to work the first time:

  1. Converted the database from latin1 to utf8 using the convert_charset tool available here: http://www.mysqlperformanceblog.com/2009/03/17/converting-character-sets/. (including setting default_character_set=utf8 in my.cnf and running SET GLOBAL character_set_server=utf8

  2. Switched to the sam-mysql-ruby adapter (instead of the standard mysql adapter: http://gemcutter.org/gems/sam-mysql-ruby)

  3. Restarted rails

The error is: "invalid byte sequence in US-ASCII" Oddly, after following the steps above the error has not changed on our production server. Setting encoding: utf8 in database.yml does not change the error either.

The error raised on the following line of code: <%= link_to h(question.title), question_path(question) %>

This blog seems to suggest a fix, but it mentions that this should not be a problem in 1.9: http://www.igvita.com/2007/04/11/secure-utf-8-input-in-rails/ (and it's over 2 years old).

I imagine this problem might soon affect a lot of people as more rails developers people switch to 1.9.


回答1:


I found the solution:

The problem is:

Fetching data from any database (Mysql, Postgresql, Sqlite2 & 3), all configured to have UTF-8 as it's character set, returns the data with ASCII-8BIT in ruby 1.9.1 and rails 2.3.2.1. (Taken from: https://rails.lighthouseapp.com/projects/8994/tickets/2476)

My attempt to use the patched mysql adapter likely failed because my database was not configured to natively use utf8, so the patched adapter failed to work properly.

The fix ended up being to use the patch file available here: http://gnuu.org/2009/11/06/ruby19-rails-mysql-utf8/

require 'mysql'

class Mysql::Result
  def encode(value, encoding = "utf-8")
    String === value ? value.force_encoding(encoding) : value
  end

  def each_utf8(&block)
    each_orig do |row|
      yield row.map {|col| encode(col) }
    end
  end
  alias each_orig each
  alias each each_utf8

  def each_hash_utf8(&block)
    each_hash_orig do |row|
      row.each {|k, v| row[k] = encode(v) }
      yield(row)
    end
  end
  alias each_hash_orig each_hash
  alias each_hash each_hash_utf8
end

(Placed in lib/mysql_utf8fix.rb and required in enviornment.rb using require 'lib/mysql_utf8fix.rb')




回答2:


it is only require 'mysql_utf8fix.rb' (rails 2.3.11)




回答3:


Please user mysql2(gem) adapter instead of mysql adapter in database.yml

and remove the mysql patches(If exists) and add the following lines in environment.rb.

Encoding.default_external = Encoding::UTF_8

Encoding.default_internal = Encoding::UTF_8

Then run in apache and passenger it ll work fine

Thanks,

Ramanavel Selvaraju.



来源:https://stackoverflow.com/questions/2090851/rails-ruby-1-9-invalid-byte-squence-in-us-ascii

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!