rails3.1でMySQLからやってくる文字列がASCII-8BITになっているのでto_jsonすると壊れる(to_jsonがencodingを見て処理するので)。sqlite3では起こらない。
環境はSnow Leopard、ruby1.9.2-p290、homebrewで入れたmysql 5.1.54。
% rails new foo
% cd foo
% vi Gemfile
(...)
gem 'mysql'
(...)
% bundle
% vi config/database.yml
(...)
development:
adapter: mysql
encoding: utf8
database: foo_development
pool: 5
username: root
password:
host: localhost
socket: /tmp/mysql.sock
(...)
% rails g model post title:string
% rake db:create
% rake db:migrate
% vi db/seeds.rb
Post.create!(title: 'うんk')
% rake db:seed
% rails c
ruby-1.9.2-p290 :001 > puts Post.first.title
うんk
=> nil
ruby-1.9.2-p290 :002 > Post.first.title.encoding
=> #<encoding:ascii-8bit>
ruby-1.9.2-p290 :003 > puts Post.first.title.to_json
"\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd"
=> nil
CentOS 5.6でも同じ。
解決:
mysql gemはruby1.9.1からのencodingに対応してない。だからmysql2を使えば解決でした。
% vi Gemfile
(...)
gem 'mysql2'
(...)
% vi config/database.yml
(...)
adapter: mysql2
(...)
% rails c
ruby-1.9.2-p290 :001 > Post.first.title.encoding
=> #<Encoding:UTF-8>
adapterにmysql2と書けるというところが盲点でした・・・。