SFE*_*ley 17 ruby ruby-on-rails utf-8 character-encoding ruby-1.9
这可能听起来很小,但它让我疯了.自上周五在Ruby 1.9上发布一个应用程序到生产以来,我一直有很多与字符编码有关的小例外.几乎所有这些都是一些变化:
Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8
Run Code Online (Sandbox Code Playgroud)
我们有一个国际用户群,所以很多名字都包含变音符号等.如果我修复模板在一堆地方使用force_encoding,它会弹出flash消息助手.等等.
目前看起来我已经确定了我所知道的所有内容,通过在一个地方修补ActiveSupport的字符串连接,然后设置# encoding: utf-8在我的每个源文件的顶部.但是我觉得我可能必须记住为我从现在开始做的每个Ruby项目的每个文件做到这一点,永远,只是为了避免字符串分配问题,并不适合我的胃.我读到了关于-Ku开关的内容,但是所有内容似乎都警告说它是为了向后兼容并且可能随时都会消失.
所以我对1.9经验丰富的人提出的问题是:#encoding我的每个文件中都设置了真正必要的吗?在全球范围内有合理的方法吗?或者,更好的方法是在绕过内部/外部默认值的字符串的非文字值上设置默认编码?
在此先感谢您的任何建议.
Til*_*ilo 13
不要将文件编码与字符串编码混淆
#encoding文件顶部的语句的目的是让Ruby在读取/解释代码时知道,并且编辑器知道在编辑/读取文件时如何处理任何非ASCII字符 - 只有在你拥有时才需要文件中至少有一个非ASCII字符.例如,在配置/区域设置文件中有必要.
要一次定义所有文件中的编码,您可以使用 magic_encoding gem,它可以将uft-8魔术注释插入应用中的所有ruby文件.
您在运行时获得Encoding::CompatibilityError的错误是在程序执行期间尝试使用不同编码连接两个字符串时发生的错误,并且它们的编码不兼容.
这很可能发生在:
您正在使用L10N字符串(例如UTF-8),并将它们连接到例如ASCII字符串(在您的视图中)
用户以外语(例如UTF-8)键入字符串,并且您的视图会尝试在某些视图中将其打印出来,以及您预定义的一些固定字符串(ASCII). force_encoding会帮助那里.还有Encoding::primary_encoding在Rails的1.9设置为新的字符串的默认编码.
还有就是config.encoding用Rails在config/application.rb中的文件.
来自数据库的字符串,然后与视图中的其他字符串组合.(他们的编码可以是两种方式,也可以是不相容的).
侧注:确保在创建数据库时指定默认编码!
create database yourproject DEFAULT CHARACTER SET utf8;
Run Code Online (Sandbox Code Playgroud)
如果要在字符串中使用EMOJI:
create database yourproject DEFAULT CHARACTER SET utf8mb4 collate utf8mb4_bin;
Run Code Online (Sandbox Code Playgroud)
并且可能包含EMOJI的字符串列上的所有索引的长度必须为191个字符.字符集utf8mb4 COLLATE utf8mb4_bin
原因是普通UTF8最多使用3个字节,而EMOJI使用4个字节存储.
请查看Yehuda Katz的这篇文章,该文章深入介绍了这一点并对其进行了解释:(特别是"不兼容的编码"部分)
http://yehudakatz.com/2010/05/05/ruby-1-9-encodings-a-primer-and-the-solution-for-rails/
http://yehudakatz.com/2010/05/17/encodings-unabridged/
和:
http://zargony.com/2009/07/24/ruby-1-9-and-file-encodings
http://graysoftinc.com/character-encodings
在你的config/application.rb添加
config.encoding = "utf-8"
Run Code Online (Sandbox Code Playgroud)
Application.initialize!在上面的行中config/environment.rb,添加以下两行:
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.