読者です 読者をやめる 読者になる 読者になる

Ruby1.9 + Rails2.5 マルチバイト文字列でエラー

MySql/Rubyruby1.9のM17Nに対応していないため
DBから取り出した文字列がすべて「ASCII-8BIT」になってしまいます。
そのため、マルチバイト文字と混在させると、下記のようなエラーが発生します。

「incompatible character encodings: UTF-8 and ASCII-8BIT」


これを暫定的に回避するために、force_encodingして対応します。

/usr/local/lib/ruby/gems/1.9.1/gems/activerecord-2.3.5/lib/active_record/attribute_methods.rb

def define_read_method(symbol, attr_name, column)
  ...
  # access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "@attributes['#{attr_name}']"
  access_code = cast_code ? "(v=@attributes['#{attr_name}']) && #{cast_code}" : "(@attributes['#{attr_name}'].class == String) ? @attributes['#{attr_name}'].force_encoding('UTF-8') : @attributes['#{attr_name}']"
  ...
end

def read_attribute(attr_name)
   ...
   # column.type_cast(value)
   (column.type_cast(value).class == String) ? column.type_cast(value).force_encoding("UTF-8") : column.type_cast(value)
   ...
end

さらにビューのほうにエンコード情報を与えます。

/usr/local/lib/ruby/gems/1.9.1/gems/actionpack-2.3.5/lib/action_view/renderable.rb

def compile!(render_symbol, local_assigns)
  ...
  source = <<-end_src
    # encoding: utf-8
    def #{render_symbol}(local_assigns)
      old_output_buffer = output_buffer;#{locals_code};#{compiled_source}
    ensure
      self.output_buffer = old_output_buffer
    end
  end_src
  ...
end

【参考サイト】
http://b.ruyaka.com/2009/07/07/ruby19-%E3%83%9E%E3%83%AB%E3%83%81%E3%83%90%E3%82%A4%E3%83%88%E6%96%87%E5%AD%97%E5%88%97%E3%81%A7%E3%82%A8%E3%83%A9%E3%83%BC-incompatible-character-encodings-utf-8-and-ascii-8bit/