Ruby初心者必見!enum完全活用法10選

プログラマがキーボードでコードを打つ様子と、enumのロゴがディスプレイ上に表示されているイメージRuby
この記事は約14分で読めます。

※本記事のコンテンツは、利用目的を問わずご活用いただけます。実務経験10000時間以上のエンジニアが監修しており、基礎知識があれば初心者にも理解していただけるように、常に解説内容のわかりやすさや記事の品質に注力しております。不具合・分かりにくい説明や不適切な表現、動かないコードなど気になることがございましたら、記事の品質向上の為にお問い合わせフォームにてご共有いただけますと幸いです。(理解できない部分などの個別相談も無償で承っております)
(送信された情報は、プライバシーポリシーのもと、厳正に取扱い、処分させていただきます。)

はじめに

プログラミングの世界は広大で、日々新たな知識を学ぶ必要があります。

そんな中でも特に、Ruby初心者が学ぶべき重要な機能の一つがenumです。

enumは一見すると複雑そうに見えるかもしれませんが、その仕組みと使い方を理解すれば、非常に強力なツールとなります。

この記事では、Rubyのenum機能を詳しく解説し、10つの詳細なサンプルコードを通じてenumの作成方法、使用例、注意点、そしてカスタマイズ方法までを学んでいきましょう。

今後のプログラミングライフにおいて、enumを活用することでより効率的で柔軟なコードを書くことができるようになります。

●Rubyのenumとは

enumとは「enumeration(列挙)」の略で、特定の集合を表すためのデータ型の一つです。

列挙とは何かというと、例えば週の曜日や季節、方角など、限定された選択肢から一つを選ぶことを意味します。

RubyのActive Recordでは、enumはデータベースの整数フィールドで特定の値の集合を表現するためのものです。

これにより、コード内で文字列を使用することなく、その値に名前を付けることができます。

enumを使用することで、コードは読みやすく、書きやすくなります。

さらに、enumを用いることで、関連するメソッドやスコープを自動的に作成することも可能になります。

これにより、コードの量を減らすことができ、同時に保守性と再利用性を向上させることができます。

次に、実際にenumの定義方法と使用例について解説していきましょう。

●enumの作成方法

○サンプルコード1:基本的なenumの定義

下記のコードは、基本的なenumの定義の例を示しています。

ここでは、Userモデルにstatusフィールドがあり、そのステータスには:active:inactive:archivedの3つの選択肢があると仮定しています。

class User < ApplicationRecord
  enum status: [:active, :inactive, :archived]
end

このコードでは、enumメソッドを使ってstatusフィールドを定義しています。

このenumは、statusフィールド

に3つの選択肢、:active:inactive:archivedを持たせています。

内部的には、これらの各ステータスは整数値で表され、データベースでは整数値として保存されます。

しかし、アプリケーションのコード内ではこれらのシンボル名でアクセスすることができます。

例えば、下記のようにすることでstatusフィールドの値を設定することができます。

user = User.new
user.status = :active
user.save

このコードを実行すると、userのstatusが:activeに設定され、それはデータベース内部では整数値として保存されます。

○サンプルコード2:ハッシュを使用したenumの定義

次に、ハッシュを使用したenumの定義方法を見てみましょう。

ハッシュを使用すると、enumの各要素に具体的な整数値を割り当てることができます。

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, archived: 2 }
end

このコードでは、statusフィールドに対して、:active:inactive:archivedの各ステータスに対応する整数値を明示的に定義しています。

この方法を使用すると、データベースに保存される整数値をコントロールすることができます。

この定義方法は、既存のデータベーススキーマにenumを追加するときや、特定の整数値を持つ既存のデータベースフィールドにenumをマッピングするときなどに有用です。

例えば、次のようにすることで、:inactiveステータスに対応する整数値を取得することができます。

user = User.new
user.status = :inactive
user.save

このコードを実行すると、userのstatusが:inactiveに設定され、それはデータベース内部では1という整数値として保存されます。

●enumの詳細な使い方

次に、enumの詳細な使い方について見ていきましょう。

enumを使うと、enumで定義した値に基づいて条件分岐を行ったり、enumに関連するメソッドを使用したり、スコープを作成したりすることができます。

それでは、それぞれの使い方についてサンプルコードを交えながら詳しく解説していきます。

○サンプルコード3:enumの値による条件分岐

まず、enumの値による条件分岐の例を見てみましょう。

下記のコードは、ユーザーのステータスが:activeかどうかを確認する例を表しています。

user = User.new
user.status = :active
user.save

if user.active?
  puts "User is active"
else
  puts "User is not active"
end

このコードでは、enumで定義した:activeステータスに対して、自動的に生成されたactive?メソッドを使用しています。

enumで定義した各値に対しては、その値と同じ名前のメソッドが自動的に生成されます。

このメソッドを使うことで、その値が現在設定されているかどうかを簡単に確認することができます。

このコードを実行すると、”User is active”と表示されます。

○サンプルコード4:enumのメソッド使用例

次に、enumのメソッド使用例を見てみましょう。

下記のコードは、ユーザーのステータスを:archivedに変更する例を表しています。

user = User.new
user.status = :active
user.save

user.archived!

このコードでは、enumで定義した:archivedステータスに対して、自動的に生成されたarchived!メソッドを使用しています。

enumで定義した各値に対しては、その値に対応する名前のメソッドが自動的に生成されます。

このメソッドを使うことで、その値を現在の値に設定し、その変更をデータベースに保存することができます。

このコードを実行すると、userのstatusが:archivedに変更され、その変更がデータベースに保存されます。

○サンプルコード5:enumのスコープ使用例

さらに、enumを使用すると、自動的にスコープも生成されます。

下記のコードは、ステータスが:inactiveの全てのユーザーを取得する例を表しています。

inactive_users = User.inactive

このコードでは、enumで定義した:inactiveステータスに対して、自動的に生成されたinactiveスコープを使用しています。

enumで定義した各値に対しては、その値と同じ名前のスコープが自動的に生成されます。

このスコープを使うことで、その値が設定されている全てのレコードを簡単に取得することができます。

●enumの注意点と詳細な対処法

それでは、enumの注意点とそれをどのように対処すれば良いのかについて説明します。

enumを使用する際には、次の2つの重要な注意点を把握しておく必要があります。

  1. enumで定義した値の変更は避けるべきです。
    enumの値を変更すると、それに対応するデータベース内の整数値との対応関係が崩れてしまい、データの整合性が失われる可能性があります。
  2. enumで定義した値は、そのモデルクラスのインスタンスメソッドとして定義されます。
    そのため、enumで定義する値が他のメソッドと名前が衝突すると、意図しない動作を引き起こす可能性があります。

それでは、これらの問題をどのように解決すれば良いのか、具体的な対処法を見ていきましょう。

○サンプルコード6:enumで定義した値の変更に対する対処法

まず、enumで定義した値の変更を避けるための対処法です。

enumの値を変更する必要が出てきた場合は、新たな値を追加し、既存の値を非推奨とするのが良いでしょう。

その上で、アプリケーションのコードを更新し、既存の値を使用している箇所を新しい値に置き換えていくのが望ましいです。

下記のサンプルコードは、:inactiveステータスを:disabledに変更したい場合の対処法を表しています。

class User < ApplicationRecord
  enum status: { active: 0, disabled: 1, archived: 2 }

  def inactive?
    ActiveSupport::Deprecation.warn("The 'inactive?' method is deprecated, use 'disabled?' instead.")
    disabled?
  end
end

このコードでは、新たに:disabledステータスを追加し、:inactiveを非推奨としています。

また、旧来の:inactive?メソッドが呼び出された際には警告を出すようにし、新たにdisabled?メソッドを使用するように促しています。

これにより、アプリケーションの他の部分がまだ旧来の:inactive?メソッドを使用している場合でも、アプリケーションが正常に動作し続けることができます。

●enumのカスタマイズ方法

次に、enumのカスタマイズ方法について解説します。

enumはその基本的な機能だけでなく、カスタマイズも可能で、プレフィックスやサフィックスを追加したり、enumで定義した値に独自のメソッドを追加したりすることができます。

○サンプルコード7:enumにプレフィックスやサフィックスを追加する方法

まず、enumにプレフィックスやサフィックスを追加する方法を見てみましょう。

下記のサンプルコードは、:activeステータスに対してプレフィックスstatus_を追加する例を表しています。

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, archived: 2 }, _prefix: :status
end

user = User.new
user.status = :active
user.save

if user.status_active?
  puts "User is active"
else
  puts "User is not active"
end

このコードでは、enumメソッドのオプションとして_prefix: :statusを指定することで、自動的に生成されるメソッドにプレフィックスstatus_を追加しています。

これにより、:activeステータスを確認するメソッドはactive?ではなくstatus_active?となります。

これは、enumで定義した値が他のメソッドと名前が衝突することを避けるために役立ちます。

○サンプルコード8:enumで定義した値に独自のメソッドを追加する方法

次に、enumで定義した値に独自のメソッドを追加する方法を見ていきましょう。

Rubyのenumでは、定義した値に対応する特定のメソッドを定義することで、そのenum値に固有の振る舞いを追加することができます。

これにより、enumを更に強力なツールとして活用することができます。

下記のサンプルコードは、:activeステータスに対して独自のメソッドnotify_if_activeを追加する例を表しています。

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, archived: 2 }

  def notify_if_active
    if active?
      puts "The user is active."
    else
      puts "The user is not active."
    end
  end
end

user = User.new(status: :active)
user.notify_if_active

このコードでは、Userクラスに新たなメソッドnotify_if_activeを定義しています。

このメソッドは、ユーザーのステータスが:activeであるかどうかを確認し、その結果に応じて異なるメッセージを表示します。

このように、enumで定義した値に対応する独自のメソッドを定義することで、そのenum値の振る舞いをより細かく制御することが可能となります。

上記のコードを実行すると、”The user is active.”というメッセージが出力されます。

これは、新たに作成したユーザーのステータスが:activeであるためです。

もしステータスが:inactive:archivedであれば、”The user is not active.”というメッセージが出力されます。

●enumの応用例とサンプルコード

これまでの説明では、enumの基本的な使い方や注意点、カスタマイズ方法について見てきました。

次に、enumの応用例とそれに対応するサンプルコードを見ていきましょう。

これらの応用例を理解することで、enumを更に活用してコードを簡潔に保つ方法が明らかになるでしょう。

○サンプルコード9:複数のenumを一つのモデルに定義する例

最初の応用例は、一つのモデルに複数のenumを定義することです。

enumは、ある特定の属性が持つべき有限の値の集合を表現するのに最適な機能です。

そのため、一つのモデルが複数のこのような属性を持つ場合、それぞれの属性に対して異なるenumを定義することが可能です。

下記のサンプルコードは、ユーザーモデルにstatusroleという2つのenumを定義する例を表しています。

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, archived: 2 }
  enum role: { member: 0, admin: 1, superadmin: 2 }
end

user = User.new(status: :active, role: :admin)
user.save

puts "User status: #{user.status}"
puts "User role: #{user.role}"

このコードでは、ユーザーのステータスと役割を表すためにそれぞれ異なるenumを定義しています。

これにより、これらの属性を簡単に管理することができます。

また、ステータスと役割の各enumは互いに独立しているため、あるenumの値が他のenumの値に影響を及ぼすことはありません。

コードを実行すると、”User status: active”と”User role: admin”という2つのメッセージが出力されます。

これは、新たに作成したユーザーのステータスが:activeであり、役割が:adminであるためです。

○サンプルコード10:enumと一緒にコールバックを使用する例

最後に、enumと一緒にコールバックを使用する例を見ていきましょう。

コールバックは特定のアクションが発生した時に実行されるメソッドで、Railsのモデルに定義することができます。

これにより、enumの値が変更されたときに特定の処理を実行することが可能となります。

下記のサンプルコードは、enumの値が:activeに変更されたときに、notify_usersというコールバックメソッドを実行する例を表しています。

class User < ApplicationRecord
  enum status: { active: 0, inactive: 1, archived: 2 }

  after_update :notify_users, if: :saved_change_to_status?

  def notify_users
    if active?
      puts "The user has become active."
    else
      puts "The user is not active."
    end
  end
end

user = User.new(status: :inactive)
user.save

user.status = :active
user.save

このコードでは、Userクラスにnotify_usersという新たなコールバックメソッドを定義し、enumのステータスが更新されたときにこのメソッドを呼び出すように設定しています。

また、このメソッドは、ステータスが:activeになったときに特定のメッセージを出力します。

上記のコードを実行すると、最初にユーザーが作成され、ステータスが:inactiveに設定されます。

その後、ステータスが:activeに変更されると、”The user has become active.”というメッセージが出力されます。

これは、ステータスの変更が保存された後で、notify_usersメソッドが呼び出されるためです。

まとめ

以上、Rubyでenumを活用するための10の方法を解説しました。

これらの方法を使って、より効率的かつ簡潔なコードを書くことができるでしょう。

初心者の方にも理解しやすいよう、詳細なサンプルコードとともに、enumの作成方法、使用例、注意点、カスタマイズ方法を学びました。

これらの情報が、あなたのRubyでのプログラミングスキルの向上に役立つことを願っています。

最後までお読みいただき、ありがとうございました。