Rails5.1でutf8mb4(絵文字)に対応させる
経緯
- マルチバイト文字を扱うとエラーが出る「Mysql2::Error: Specified key was too long; max key length is 767 bytes limit」
- rails5までは、カロリさんの記事を参考にutf8mb4に対応させていたが、
alias_method_chain で書かれていた - Rails5 で alias_method_chain が deprecated され、Rails5.1 で alias_method_chain がなくなった
- 大したことではないがそれをprependで書き直し、プロジェクトを作るときによく使うのでメモとしてまとめます
utf8mb4にする方法
手順としてはDBとRailsの設定をすればOK
- RDS or MySQLの設定
- Railsの設定
1. MySQL or RDSの設定
●RDSの場合
Parameter Groupsを新たに作成し、
- character_set_client
- character_set_connection
- character_set_database
- character_set_results
- character_set_server
の設定値を、下図のようにしておきます。
また、「init_connect」と「skip-character-set-client-handshake」 も以下のように設定します。
- skip-character-set-client-handshake
- 1
- init_connect
- SET NAMES utf8mb4;
そして、パラメータグループを適用し、「今すぐ適用」にチェックして 変更 すれば、RDS側の設定はOKです。
●MySQLの場合
- my.cnfにutf8mb4の設定を書いて、再起動します。
my.cnf
[mysql]
default-character-set=utf8mb4
[mysqld]
character-set-server = utf8mb4
skip-character-set-client-handshake
character-set-server = utf8mb4
collation-server = utf8mb4_general_ci
init-connect = SET NAMES utf8mb4
innodb_file_format = Barracuda
innodb_file_per_table = 1
innodb_large_prefix
2. Railsの設定
2つのファイルを編集します
- config/database.yml
- config/initializers/utf8mb4.rb
database.ymlを編集
- defaultのところでutf8mb4を使うようにします
config/database.yml
default: &default
adapter: mysql2
charset: utf8mb4
encoding: utf8mb4
collation: utf8mb4_unicode_ci
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: <%= ENV['DB_USER'] %>
password: <%= ENV['DB_PASS'] %>
development:
<<: *default
database: hoge_development
test:
<<: *default
database: hoge_test
staging:
<<: *default
host: <%= ENV['DB_HOST'] %>
database: <%= ENV['MYSQL_DB'] %>
production:
<<: *default
host: <%= ENV['DB_HOST'] %>
database: <%= ENV['MYSQL_DB'] %>
config/initializers/utf8mb4.rbを作成
- create_tableのときにutf8mb4のオプションを渡すようにします
config/initializers/utf8mb4.rb
module Utf8mb4
def create_table(table_name, options = {})
table_options = options.merge(options: 'ENGINE=InnoDB ROW_FORMAT=DYNAMIC')
super(table_name, table_options) do |td|
yield td if block_given?
end
end
end
ActiveSupport.on_load :active_record do
module ActiveRecord::ConnectionAdapters
class AbstractMysqlAdapter
prepend Utf8mb4
end
end
end
参考記事など
- https://blog.hello-world.jp.net/mysql/2063/
- https://blog.hello-world.jp.net/mysql/2055/
- http://dev.classmethod.jp/cloud/aws/utf8mb4-on-rds-mysql/
まとめ
- 誰でも簡単にマルチバイト文字列に対応することができました!!
- 修正点や間違っているところなどあれば、教えていただきたいです><
- ありがとうございました!!