Edited at

ActiveRecordをutf8mb4で動かす

More than 3 years have passed since last update.

もうMySQL 5.5 GAが出てから一年が経ち、MySQL 5.6 GAもそろそろ出るころだし、新規で作るアプリケーションはutf8mb4でいきたいのでその方法。

まず、mysql2が0.3.11以前のバージョンではutf8mb4に対応してないので、それより新しいバージョンを使う必要があります。

gem 'mysql2', '>= 0.3.12b4'

これでencoding: utf8mb4で接続できるようになります。

つぎにActiveRecord::Migrationでutf8mb4なデータベースを作成するようにコンフィグでcharsetcollationを指定します。


config/database.yml

development:

adapter: mysql2
encoding: utf8mb4
charset: utf8mb4
collation: utf8mb4_general_ci
reconnect: false
database: kamipo_development

そうすると、schema_migrationsがインデックス張れないエラーでこけます。

Mysql2::Error: Index column size too large. The maximum column size is 767 bytes.: CREATE UNIQUE INDEX `unique_schema_migrations` ON `schema_migrations` (`version`)

MySQL側のinnodb_large_prefixオプションでキープレフィックスを3072バイトまで拡張できるのでmy.cnfで指定します。


my.cnf

[mysqld]

innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix

このオプションはROW_FORMATがDYNAMICかCOMPRESSEDのとき有効なので、create_tableメソッドで'ROW_FORMAT=DYNAMIC'がデフォルトで指定されるようにしておきます。


config/initializers/ar_innodb_row_format.rb

ActiveSupport.on_load :active_record do

module ActiveRecord::ConnectionAdapters

class AbstractMysqlAdapter
def create_table_with_innodb_row_format(table_name, options = {})
table_options = options.merge(:options => 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC')
create_table_without_innodb_row_format(table_name, table_options) do |td|
yield td if block_given?
end
end
alias_method_chain :create_table, :innodb_row_format
end

end
end


これでとりあえずutf8mb4で動きます!


参考