8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

MySQL+ActiveRecord環境で絵文字に対応したお話

Last updated at Posted at 2017-12-20

mixiグループ Advent Calendar 2017 の21日目です。

XFLAGスタジオ CRE(Customer Reliability Engineering)チームの @njin です。

:triangular_flag_on_post: はじめに

CREチームの業務の一つに、カスタマーサポート(CS)スタッフ向けの管理画面(CSツール)の開発があります。
今回は最近実装したCSツールの機能で起きた問題とその解決方法についてまとめました。

CREとは?CREチームって何やってるの?など
ご興味を持っていただけた方は、こちらの記事もご覧になってみてください。
CREチームのメンバーがAdvent Calendarに参加しております :smile:
CREチームを設立しました!(@otoyo)
アプリケーションサーバに引きこもるDBを自立させてDocker Composeで開発環境を作る(@upscent)
なれる!CRE(@nukosuke)
フェイルセーフの観点から顧客信頼性を確保しよう(@manji602)

:triangular_flag_on_post: 機能の概要

XFLAGスタジオのCSでは、多くのプロダクトでCS対応にZendeskというCRMを使用しています。
Zendeskではお問い合わせ1件1件を「チケット」と呼ばれるものに紐づけて管理しています。

詳細は書けないのですが、今回追加した機能の簡略化したフローは以下です。

  1. ZendeskからAPIでチケット単位のデータ(JSON形式)を取得
  2. 取得したチケットのデータをDBへ保存
  3. 保存したデータを整形し、CSツールで表示

Pasted image at 2017_12_15 10_49 AM.png

チケットにはお問い合わせの内容やアカウントのID・ニックネーム・ランクなどが記載されたメール本文が含まれており、ここである問題が発生しました。

:triangular_flag_on_post: 問題

CSスタッフから連絡があり、CSツールでユーザーの情報が途中から表示されていないというのです。
さらにニックネームに絵文字が含まれていると聞き、嫌な予感がしました…

DBのデータを確認すると、ニックネームから後ろが切れています。

[1] pry(main)> ticket.body
=> "【お問い合わせ内容】\r\nhogehogeについて\r\n\r\n【項目1】\r\ntest\r\n\r\n【項目2】\r\ntest\r\n\r\n【ニックネーム】\r\n"

テーブルの定義を確認すると、

> SHOW CREATE TABLE tickets;
| tickets | CREATE TABLE `tickets` (
`body` text NOT NULL,
...
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |

そうですよね。

テーブル作成時にCHARSETをutf8mb4に設定していないことが原因でした。
テーブルやカラムがutf8mb4に対応していない場合、絵文字(4バイト文字)が含まれているとそれ以降がカットされてしまいます。

[1] pry(main)> ticket = Ticket.create(body: "すし🍣すし")
[2] pry(main)> ticket.body
=> "すし"

:triangular_flag_on_post: 解決方法

追加した機能がすでに稼働している状況だったため、テーブルの作り直しではなく、CSの業務時間外に change_column を使ったカラム変更でCHARSETをutf8からutf8mb4へ変更することにしました。
change_column でCHARSETを変更するための記法がわからず少々苦戦しましたが、以下の記述で変更することができました。

class ChangeColumn < ActiveRecord::Migration
  def self.up
    change_column :tickets, :body, "text CHARSET utf8mb4"
    ...
  end
end
[1] pry(main)> Ticket.create(body: "すし🍣") 
SELECT * FROM tickets;
+----+------------------------------+
| id | body                         |
+----+------------------------------+
|  1 | すし????                      |
+----+------------------------------+

絵文字以降も保存されるようになりましたが、文字化けした状態で保存されてしまいました。
そこで、RailsとMySQLでiOSの絵文字に対応(UTF8MB4化)した話を参考に、ActiveRecordでMySQLへ接続する際のCHARSETをutf8mb4に設定することで解決しました。

config/database.yml
development:
  encoding: utf8mb4

test:
  encoding: utf8mb4

production:
  encoding: utf8mb4
[1] pry(main)> Ticket.create(body: "すしすし🍣🍣")
SELECT * FROM tickets;
+----+------------------------------+
| id | body                         |
+----+------------------------------+
|  1 | すし????                      |
|  2 | すしすし🍣🍣                    |
+----+------------------------------+

文字化けせずに保存できました。

:triangular_flag_on_post: 終わりに

CSツールに不具合が発生しCSツールが停止すると、CSスタッフは対応ができなくなり、それはそのままユーザーさんへの返信の遅れに直結します。

CREチームのメンバーとして、より速く・正確なCS対応のサポートをしていけるように、CSツールの開発についても「より速く・正確な」を意識して取り組んでいきたいと思います。

参考URL

RailsとMySQLでiOSの絵文字に対応(UTF8MB4化)した話

8
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?