💎

[Ruby on Rails] 文字列の配列形式を安全に配列化する方法

2024/04/30に公開

最近、英語の勉強方法(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

どのケースでも全て配列形式で返すようにしています。

  1. licenseが空の場合(nil[]など)は空の配列を返します。
    これによりTypeErrorが発生することを防ぎます。
  2. begin〜endブロック内でJSON.parseを実行し、配列化を試みます。
    正常かつ配列の場合は、そのまま配列を返します。
    正常かつ配列じゃない場合(ハッシュ形式など)は、配列にして返します。
  3. JSON::ParserErrorが発生した場合は、rescueブロックで元の文字列を配列にして返します。

このようにレスキューすることで、データのフォーマットが多少おかしくても、アプリケーション全体が止まることなく適切なアウトプットを返すことができます。

モデルでserializeを使う方法

上記の方法は便利ですが、可読性は若干低くなります。もっと良い方法としては、モデルでserializeを使う方法があげられます。

class YourModel < ApplicationRecord
  serialize :license, Array
end

このようにすれば、licenseカラムのデータを自動的に配列化してくれるので、コントローラーやビューでは配列としてアクセスできます。この方法の方が、可読性が高く推奨されます。

まとめ

今回は、文字列の配列形式のデータを安全に配列化する方法について解説しました。JSON.parseを使う場合はレスキューを忘れずに行い、さらに良い方法としてモデルでserializeを使うことをおすすめします。適切な方法を選んで、アプリケーションの安定性を高めましょう。

Archibase Tech Blog

Discussion