Rails
MySQL
utf8mb4
rails5.1

Rails5.1でutf8mb4(絵文字)に対応させる

Rails5.1でutf8mb4(絵文字)に対応させる

Gizmodo_201608_emoji-siri-carplay.jpg

経緯

  • マルチバイト文字を扱うとエラーが出る「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
1. RDS or MySQLの設定
2. Railsの設定

1. MySQL or RDSの設定

●RDSの場合

Parameter Groupsを新たに作成し、

  • character_set_client
  • character_set_connection
  • character_set_database
  • character_set_results
  • character_set_server の設定値を、下図のようにしておきます。

スクリーンショット 2017-06-11 15.10.09.png

また、「init_connect」と「skip-character-set-client-handshake」 も以下のように設定します。

  • skip-character-set-client-handshake

    • 1 スクリーンショット 2017-06-11 15.10.38.png
  • init_connect

    • SET NAMES utf8mb4;

スクリーンショット 2017-06-11 15.10.53.png

そして、パラメータグループを適用し、「今すぐ適用」にチェックして 変更 すれば、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

参考記事など

まとめ

  • 誰でも簡単にマルチバイト文字列に対応することができました!!
  • 修正点や間違っているところなどあれば、教えていただきたいです><
  • ありがとうございました!!