【Rails、MySQL】configの文字コードを変えずに、一部で絵文字を保存&表示する
Railsのデフォルトの文字コード(utf-8)だと絵文字が保存できないので、使えるようにしたいってとき、あると思います。
おそらく、「✌️」こういう絵文字は保存できるけれど、「😊」こういった顔文字は保存できないはず。
では、絵文字を使えるように変更しようと、調べて出てくるのは、文字コードをutf-8からutf8mb4に変えるといった記事です。
ただ、文字コードを途中で変更するとなると色々リスクがありそう。
utf8→utf8mb4の場合は、拡張的な感じなので大きなリスクがあるわけではなさそうですが、少しでもリスクがある以上、安易に変更はしたくない。
そこで、今回はconfig の文字コードの設定は変えず、一部だけ絵文字を使えるようにする方法を記事にしました。
いきなり結論
いきなり結論をお伝えします。
データを保存する際に、string型ではなく、binary型として保存し、
表示の際に、UTF-8として表示します。
コードの例
Profileモデルのニックネームに絵文字を使えるようにしたい場合を例とします。
①profileモデルのnicknameのデータ型をstringではなく、binary型として設定する
create_table "profiles", force: :cascade do |t|
t.integer "user_id"
t.binary "nickname"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
これで保存する際に文字列ではなく、バイナリ型として保存されるようになります。
バイナリ型について
https://www.dbonline.jp/mysql/type/index5.html
②Profileモデルのメソッドに、表示する際の変換処理を書く
def nickname
read_attribute(:nickname).try(:force_encoding, 'UTF-8')
end
分解します。
read_attribute(:nickname)
ここで、nicknameカラムの値を取得できるようにしているよう
https://qiita.com/KenjiOtsuka/items/43540cd372ce7cf1d8b5
try(:force_encoding, 'UTF-8')
tryは、ぼっち演算で、
オブジェクトがnilの時やメソッドが定義されていない場合はnilを返す
メソッドが定義されている場合はそのメソットを呼び出す
https://railsdoc.com/page/try
forth_encordingで、指定した('UTF-8')の文字コードに変換
https://docs.ruby-lang.org/ja/latest/method/String/i/force_encoding.html
③viewでnicknameを呼び出す
<p><%= current_user.profile.nickname %></p>
このように記載することで、バイナリ型として保存していたデータがutf-8として変換され表示できます。
ちなみに、なぜこうnicknameと書くだけで呼び出せるのかっていうと、この記事が参考になります。
https://hiratano.hatenablog.com/entry/2021/01/05/213048
一言でいうと「Ruby on Railsではカラムのデータを取り出すための、カラム名と同じ名前のメソッドが自動で作られている」
自分で作った②のnicknameというメソッドが、Railsが自動で作ってくれたnicknameというメソッドを上書きしてるみたいです。
以上です。
ただ、この方法は一部だけ使えるようにするって方法なので、使えるようにしたい箇所が多い場合は、文字コードを変えるなど別の方法を使ったほうがいいと思います。