前回の続き
http://b.ruyaka.com/2009/07/06/ruby19-gem-install-mysql-ではまる/
なんかgem install mysqlでMySQL/Rubyはインスートルできたんですが、
どうやらMySQL/Rubyがruby1.9の「M17N」に対応していない模様。
おかげて、データベースから取り出した文字列は全て「ASCII-8BIT」になってしまいます。
マルチバイト文字列を入れるとASCII-8BITとUTF-8がぶつかりエラーが発生します。
「incompatible character encodings: UTF-8 and ASCII-8BIT」
ほんと困りました。
調べてみたところ解決方法は2通り発見。
① MySQL/Rubyではなく、M17Nに対応しているRuby/MySQLを入れる (ややこしい)
② Rails上で「force_encoding(“UTF-8”)」で無理やり「UTF-8」に変更する。
①の「Ruby/MySQL」はtmtmsさんが作成してくれてました。
RubyコンパイルされているRuby/MySQL 3.0.0がでています。
ただ、アルファ版というのと、いくつか不安な部分もあったので今回は②番で対応することに。
②の変更点
ちょっと強引ですが、read_attributesの部分で文字列がきたら強制的に「UTF-8」になるように変更。
一応これでエラーはでなくなりました。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<textarea class="html" cols="60" rows="5" name="code"> def define_read_method(symbol, attr_name, column) cast_code = column.type_cast_code('v') if 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}']" unless attr_name.to_s == self.primary_key.to_s access_code = access_code.insert(0, "missing_attribute('#{attr_name}', caller) unless @attributes.has_key?('#{attr_name}'); ") end if cache_attribute?(attr_name) access_code = "@attributes_cache['#{attr_name}'] ||= (#{access_code})" end evaluate_attribute_method attr_name, "def #{symbol}; #{access_code}; end" end </textarea> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<textarea class="html" cols="60" rows="5" name="code"> vendor/rails/activerecord/lib/active_record/attribute_methods.rb :273行 def read_attribute(attr_name) attr_name = attr_name.to_s if !(value = @attributes[attr_name]).nil? if column = column_for_attribute(attr_name) if unserializable_attribute?(attr_name, column) unserialize_attribute(attr_name) else - column.type_cast(value) + (column.type_cast(value).class == String) ? column.type_cast(value).force_encoding("UTF-8") : column.type_cast(value) end else </textarea> |
上記はActiveRecord周りの文字コードの対応ですが、
テンプレートのほうも対応するようにしてあげる必要があるようです。
vendor/rails/actionpack/lib/action_view/renderable.rb: 69行目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<textarea class="html" cols="60" rows="5" name="code"> def compile!(render_symbol, local_assigns) locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join 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 </textarea> |
これでなんとか対応完了。
かなり強引ですが、他もっと簡単なやり方があると教えていただけると助かります。
以下、参考サイト
http://groups.google.co.jp/group/rubyonrails-talk/browse_thread/thread/45cf95921c8fe21f
http://74.125.155.132/search?q=cache:LMULoqmE-SMJ:d.hatena.ne.jp/tmtms/20090201/1233499176+%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9%E3%81%8B%E3%82%89%E5%8F%96%E3%82%8A%E5%87%BA%E3%81%97%E3%81%9F%E6%96%87%E5%AD%97%E5%88%97%E3%81%AF%E3%80%81%E5%85%A8%E9%83%A8+ASCII-8BIT+%E3%81%AB%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99&cd=2&hl=ja&ct=clnk&gl=jp&lr=lang_ja&client=firefox-a
http://e-words.jp/w/M17N.html
http://d.hatena.ne.jp/tmtms/20090322/1237719050
http://d.hatena.ne.jp/xibbar/20090126/1232946944
http://qwik.jp/asakusarb/56.html