railsでMySQLのレコードの日本語が16進数で表示されてしまう。
railsでmysqlを使った際にレコード内の日本語が16進数(hex)で表示されてしまう問題です。
環境
Amazon Linux AMI release 2015.03 (EC2) MySQL5.6 (RDS) nginx version: nginx/1.6.2 unicorn v4.9.0 Rails 4.2.0 ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
AWSでnginx+unicornの上でrailsを動かしています。production環境です。
症状
railsコンソールで入力すると以下のようになります。
irb(main):001:0> Prefecture.new(name:"あああああ").save SQL (0.4ms) BEGIN SQL (1.2ms) INSERT INTO `prefectures` (`name`, `created_at`, `updated_at`) VALUES (?, ?, ?) [["name", "あああああ"], ["created_at", "2015-08-14 04:55:42"], ["updated_at", "2015-08-14 04:55:42"]] (5.9ms) COMMIT => true irb(main):002:0> Prefecture.last Prefecture Load (0.9ms) SELECT `prefectures`.* FROM `prefectures` ORDER BY `prefectures`.`id` DESC LIMIT 1 => #<Prefecture id: 1, name: "\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82", created_at: "2015-08-14 04:55:42", updated_at: "2015-08-14 04:55:42">
あああああと入力したnameが\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82\xE3\x81\x82と表示されています。
mysql> show variables like 'char%'; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | latin1 | | character_set_connection | latin1 | | character_set_database | latin1 | | character_set_filesystem | binary | | character_set_results | latin1 | | character_set_server | latin1 | | character_set_system | latin1 | | character_sets_dir | /rdsdbbin/mysql-5.6.23.R1/share/charsets/ | +--------------------------+-------------------------------------------+ 8 rows in set (0.00 sec)
latin1ってなんやねん。
RDSを使っているのでRDSコンソールから文字コードの設定をします。
RDSの文字コード設定
まずRDSコンソールにアクセスします。
ここの「パラメーターグループ」にアクセスして「パラメーターグループの作成」をします。
名前とかは適当で大丈夫です。作成したら「パラメーターグループの編集」をクリックします。
そこのcharacter_set_*を以下のように変更します。
これでRDSの変更は完了です。
ターミナルで確認
mysql> show variables like 'char%'; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8 | | character_set_connection | utf8 | | character_set_database | utf8 | | character_set_filesystem | binary | | character_set_results | utf8 | | character_set_server | utf8 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.6.23.R1/share/charsets/ | +--------------------------+-------------------------------------------+ 8 rows in set (0.00 sec)
よっしゃ。
railsコンソールで確認すると、まだ16進数で表示されています。なんでだろう。
SQL文直接打って確認
直接打って確認します。
mysql> select name from prefectures; +--------------+ | name | +--------------+ | ああああ | | ああああ | +--------------+ 2 rows in set (0.00 sec)
お、表示できてる。
つまり、developのsqliteではちゃんと表示されていたので、この問題の原因はMySQLのrailsでの取り扱いにあるようです。
解決
gemに問題がありました。Gemfile内のgem 'mysql'をgem 'mysql2'に変更してconfig/database.ymlのadapterをmysql2に修正したらちゃんと日本語が表示されるようになりました。
#Gemfile gem 'mysql2'
#config/database.yml
production:
adapter: mysql2
こんな感じにしたら治りました。
まとめ
mysqlでも中途半端に動くというのが一番問題です。
mysqlとmysql2の違いを調べているのですが、速度の話が多いです。。。
恐らく、mysqlはただただ日本語に対応していないだけだと思います。