rails encoding

如果你用Ruby 1.9不会没有遇到过编码的问题吧,Ruby 1.9支持强大的m17n,强大到我一开始接触它都要疯掉了。。。 作为一个好屁民我决定把我的痛苦经历写一写,毕竟我还没见过这方面的中文介绍。Ruby是一种很特别的语言,Ruby 1.9更是个神奇的存在。我是用Ruby 1.9后才知道还有m17n这一说法的,看来我太寡聞了么。 我遇到的错误,相信你也遇到过,除非你都用的ASCII码或者你比Ruby更怪 ActionView::Template::Error (incompatible character encodings: ASCII-8BIT and UTF-8) 伟大的革命精神是怎样的?克服一切困难,没有问题也要制造问题然后解决它。解决问题之前,先来介绍一点Ruby 1.9 encoding的处理方式。 谈到编码,自然就要讲字符串,Ruby 1.9中的字符串不是一个人,他已经被编码附体了! 一个String对象不仅包含着一般意义上的字符串,还有一个Encoding对象与它关联 irb(main):014:0> s = '中文' => "中文" irb(main):015:0> s.encoding => # 而编码问题一般发生在字符串连接时,让我们践行伟大的无产阶级革命精神创造麻烦吧 irb(main):026:0> s.force_encoding('BINARY') => "/xE4/xB8/xAD/xE6/x96/x87" irb(main):027:0> x = '也是中文' => "也是中文" irb(main):028:0> x.encoding => # irb(main):029:0> s x Encoding::CompatibilityError: incompatible character encodings: ASCII-8BIT and UTF-8 麻烦已经被我们制造出来了,可以看到与上面的错误是一样的,我们要做的就是解决掉它。 首先找到问题代码的位置在action_view/template/handlers/erb.rb,我们写一个initializer覆盖它。 # config/initializers/rails/action_view/template/handlers/erb.rb require "action_view/template/handlers/erb" ActionView::OutputBuffer.class_eval do undef if respond_to?(:) def (value) self.force_encoding(Encoding.default_external) value = value.to_s.force_encoding(Encoding.default_external) super(value) end alias :append= : end 代码意思很明确,在erb需要拼接时把双方都转化为Encoding.default_external,这个在Rails里默认是UTF-8的。 问题解决了吗?不!革命一定要彻底,把能找到的隐患全部消灭。数据库里读取数据自然不会少了字符串,编码也一定如影随形 # config/initializers/rails/active_record/connection_adapters/sqlite_adapter.rb require 'active_record/connection_adapters/sqlite_adapter' module ActiveRecord module ConnectionAdapters SQLiteAdapter.class_eval do undef select if respond_to?(:select) protected def select(sql, name = nil) execute(sql, name).map do |row| record = {} row.each do |k, v| if k.is_a?(String) v.force_encoding(Encoding.default_external) if v.respond_to?(:force_encoding) record[k.sub(/^"?/w+"?/./, '')] = v end end record end end end end end 我可是sqlite3的坚决拥趸,自然就只顾着sqlite3了。 另一个问题是表单提交的信息,只要有字符串产生的地方就有编码隐患,消灭它 # config/initializers/rails/action_dispatch/http/parameters.rb require 'action_dispatch/http/parameters' module ActionDispatch module Http module Parameters undef normalize_parameters if respond_to?(:normalize_parameters) private def normalize_parameters(value) case value when Hash h = {} value.each { |k, v| h[k] = normalize_parameters(v) } h.with_indifferent_access when Array value.map { |e| normalize_parameters(e) } else value.force_encoding(Encoding.default_external) end end end end end 多谢呼呼的提示,到最后我还是采纳了他的方案,现在问题暂时被解决了。 当然这些作案方式都是些很无耻的写法,如果一切都这么简单,Rails开发小组是不会把问题留给我的,嘻哈。 至于Ruby为什么选用现在的m17n,而不是像其他大部分语言在内部统一的使用一种编码,比如UTF-8。据说是为了方便不同编码的程序员搞基顺利?为了给程序员选择的自由?啊,我宁愿不要这种自由 想深入了解,这是对字符编码和Ruby字符处理的一系列文章Understanding M17n
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值