rails mysqlでiPhoneアプリの絵文字対応
超久しぶりの更新 大丈夫生きてます。
色々あって今iPhoneアプリを作っていて
そのアプリで絵文字を使いたくて結構はまったので、対応したメモを残しておく。
ユーザーがDBに突っ込んでくるテキストに絵文字が入っていてrailsとDBはmysqlを使ってる。
Mysql2
railsでmysql2を使ってるが、gem mysql2がutf8mb4に対応していないので
下記を参考にbundleで入れたmoduleに手を入れた。
AWS - Rails + Mysql(utf8mb4) on Amazon RDS - Qiita
add utf8mb4 charset · f535df8 · brianmario/mysql2 · GitHub
mysql2の更新が待たれる。。。
Gemfileに下記を追加してもいいかも
gem 'mysql2', :git => 'git://github.com/tmtm/mysql2.git', :branch => 'utf8mb4'
database.ymlを変更しエンコードをutf8 -> utf8mb4に変更する
production: adapter: mysql2 database: test encoding: utf8mb4
databaseをutf8mb4で作成する
create database test DEFAULT CHARACTER SET utf8mb4;
DBをマイグレーションする
※ utf8(3バイト) -> utf8mb4(4バイト)になったことにより
primary key, unique keyインデックスのbyteが767以上になってしまうカラムがあるのでVARCHARカラムなどは適切な値で正規化する
MySQLのUNIQUEなINDEXには長さ767byteまでしか使えない件と対策 - tanamonの日記
※ railsがデフォルトで作るschema_migration用のversionカラムも上記に該当するのでversionカラムをVARCHAR(15)に変更する
Rails3 と MySQL な環境で Unicode の絵文字を使う - SmallStyle(2011-12-05)
/vendor/bundle/ruby/1.9.1/gems/activerecord-3.2.2/lib/active_record/connection_adapters/abstract/schema_statements.rb
419行目を修正
schema_migrations_table.column :version, :string, :null => false, :limit => 15
railsからはJSONでアプリにレスポンスを返す仕様
jsonで出力する際にrailsがマルチバイト文字をescapeしている。
※下記が該当コード
http://blog.sosedoff.com/2012/04/26/emoji-and-rails-json-output-issue/
しかしこれは \u{123}とか\u{12345}みたいな4バイト以上の文字はescapeをミスる
Emoji range encoded in JSON mangled · Issue #3727 · rails/rails · GitHub
escapeを行っている ActiveSupport::JSON::Encodingを下記のようなファイルを作って対応
config/initializers/active_support_encoding.rb
module ActiveSupport::JSON::Encoding class << self def escape(string) if string.respond_to?(:force_encoding) string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY) end json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] } json = %("#{json}") json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding) json end end end
参考 : http://blog.sosedoff.com/2012/04/26/emoji-and-rails-json-output-issue/
これでなんとか対応できた。