モデルの生成
たとえば user モデルを作るとします。
すると同時にマイグレーションファイルも生成されますが、これが「ローカルでは動くけどステージング(RDS)では動かない」という事件を引き起こしてくれます。
$ rails g model user name:string email:string
class CreateUsers < ActiveRecord::Migration
def change
create_table :users do |t|
t.string :name
t.string :email
t.timestamps
end
end
end
ローカルでは動くけどステージング(RDS)では動かない
ローカルでは同梱の SQLite3、もしくはそれ用にインストールした MySQL を利用すると思います。
そのローカルで十分検証したのち、ステージング(DB の向け先が RDS の)環境にデプロイすると、周りから「日本語が文字化けしています。調査をお願いします。」という連絡がきます。
原因は RDS(MySQL)の文字コード
RDS(MySQL)の文字コードはデフォルトでは latin1 が使用されるようになっています。
そのため、先ほどのマイグレーションファイルをそのまま適用すると latin1 でカラムが作られてしまって、日本語が扱えないという事件が起こってしまいます。
$ mysql -u xxx -pYYY -h zzz.rds.amazonaws.com
mysql> show create table users \G
〜 中略 〜
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1
対策1:RDS の設定を変更する
AWS コンソールから RDS ->Parameter Groups
といって、下記のパラメータを utf8 に修正しましょう。
- character_set_client
- character_set_connection
- character_set_database
- character_set_results
- character_set_server
対策2:マイグレーションファイルで charset を指定する
マイグレーションファイルの options
で charset を指定します。
class CreateUsers < ActiveRecord::Migration
def change
create_table(:users, :options => 'ENGINE=InnoDB DEFAULT CHARSET=utf8') do |t| # <--「utf8」を指定
t.string :name
t.string :email
t.timestamps
end
end
end
付け足し
対策1/対策2ともに、対応前に生成されたテーブルは latin1 のままなので、drop ->create
で作り直すか、alter table <テーブル名> convert to charcter set utf8
で変更するような対応が必要になります。
まとめ
どちらの対応でも問題ないですが、場合によってはインフラを変更できないようなプロジェクトも存在すると思うので、MySQL を利用する際は 対策2 の対応を取るような癖をつけておけば良いと思います。