[Ruby on Rails] 文字列の配列形式を安全に配列化する方法
最近、英語の勉強方法(Immersion Learning
)にハマってきてるエンジニアの秋山です。
今回は、文字列の配列形式のデータを安全に配列化する方法について解説したいと思います。
はじめに
この記事を書こうと思ったきっかけは、過去に一覧ページの一部で500エラーが発生したことがあり、その際に反省点が浮かんだからです。当時はJSON.parse
を使用する箇所で適切な例外処理を行っておらず、フォーマットが間違ったデータが渡された場合にアプリケーション全体が止まってしまうリスクがありました。
この経験から、今後はJSON.parse
を使う箇所では必ずbegin〜rescue
によるレスキューを行うべきだと気づきました。適切にエラーハンドリングを行えば、フォーマットが多少おかしくてもアプリケーションが止まることなく、ある程度適切なアウトプットを返すことができます。
そこで今回、このJSON.parse
の安全な使い方について、具体的な実装例を交えてご紹介したいと思います。
なぜ安全な配列化が必要なのか
時々、カラムにテキストベースの配列形式でデータを保存する必要があるケースがあります。
例えば、license
という資格の情報を保存するカラムがあり、そのデータが'["aaa", "bbb"]'
のような文字列の配列形式で保存されている場合です。
このようなデータを配列化する際に、JSON.parse
を使うことがよくあります。しかし、データにフォーマットの間違いがあると、JSON::ParserError
が発生し、ページ全体が表示されなくなる500エラーが起こる可能性があります。このような事態は避けたいです。
安全に配列化する方法
エラーが発生しても適切に処理できるよう、begin〜rescue
を使ってレスキューする必要があります。具体的な実装例は以下の通りです。
def licenses
return [] if license.blank?
begin
JSON.parse(license).then { |j| j.is_a?(Array) ? j : [j] }
rescue JSON::ParserError
[license]
end
end
どのケースでも全て配列形式で返すようにしています。
-
license
が空の場合(nil
や[]
など)は空の配列を返します。
これによりTypeError
が発生することを防ぎます。 -
begin〜end
ブロック内でJSON.parse
を実行し、配列化を試みます。
正常かつ配列の場合は、そのまま配列を返します。
正常かつ配列じゃない場合(ハッシュ形式など)は、配列にして返します。 -
JSON::ParserError
が発生した場合は、rescueブロックで元の文字列を配列にして返します。
このようにレスキューすることで、データのフォーマットが多少おかしくても、アプリケーション全体が止まることなく適切なアウトプットを返すことができます。
serialize
を使う方法
モデルで上記の方法は便利ですが、可読性は若干低くなります。もっと良い方法としては、モデルでserialize
を使う方法があげられます。
class YourModel < ApplicationRecord
serialize :license, Array
end
このようにすれば、license
カラムのデータを自動的に配列化してくれるので、コントローラーやビューでは配列としてアクセスできます。この方法の方が、可読性が高く推奨されます。
まとめ
今回は、文字列の配列形式のデータを安全に配列化する方法について解説しました。JSON.parse
を使う場合はレスキューを忘れずに行い、さらに良い方法としてモデルでserialize
を使うことをおすすめします。適切な方法を選んで、アプリケーションの安定性を高めましょう。
Discussion