Railsでenumを自由自在に操る

Rails・Webシステム開発
Anja🤗#helpinghands #solidarity#stays healthy🙏によるPixabayからの画像
スポンサーリンク

enumは、DBにはint型(数字)で保存でき、CRUDは人間の言葉で操作できる、大変便利な仕組みですよね。

しかし、数字/英語/日本語の3つの表現があるために思うようにいかないときもあるのでは?

特に、初学者が最初に躓くのがenumをform_withでf.selectさせる時ですよね!

基本を知らないと難しいですが、基本を押さえればそれほど難しいことではないことが最近わかったので、それぞれの対応を整理しておきます。



enumを設定する(前提条件)

Rails6 × MySQL

db/schema.rb:カラムの型はinteger(DBには整数で格納される)

create_table "articles" do |t|
  t.integer "status", null: false, default: 0
  # (中略)
end

app/models/article.rb:モデルを設定

class Article < ApplicationRecord
  # (中略)
  enum status: { 
    close: 0, 
    open: 1
  }
end

数字→英語だけなら以上の設定のみでもOK。日本語も導入する場合は下記の設定も行う。

Gemfile:日本語化のためのgemを導入

gem 'rails-i18n'
gem 'enum_help'

config/application.rb:日本語化しておく

module SampleApp
  class Application < Rails::Application
    # (中略)
    config.i18n.default_locale = :ja
    config.i18n.load_path += Dir[Rails.root.join('config', 'locales', '**', '*.{rb,yml}').to_s]
  end
end

config/locales/ja.yml:localesで日本語を設定

ja:
  enums: 
    article: 
      status: 
        close: '非公開'
        open: '公開'

本記事は、上記のように、enumの設定×日本語化の設定が済んでいる状態を前提に書いていきます。

locales配下をディレクトリで分けたり、ja.ymlではなくファイル名を変えることはあると思いますが、それでも以下のメソッドは変わらず使えます。

bundle installやサーバーの立ち上げ直しも忘れずに。



enumを変換する(これを押さえれば応用が効く!)

英語↔数字

class Article(Articleモデル)で定義したハッシュをそのまま使います。

英語→数字

「モデル名.enumのカラム名の複数形」でハッシュが返ってきます。

>> Article.statuses
=> { close: 0, open: 1}

したがって、下記のようにすれば変換できます。

>> Article.statuses["open"]
=> 1

数字→英語

これはあまり使わないかもしれませんが、invertメソッドを使って英語→数字の逆を利用します。

>> Article.statuses
=> { close: 0, open: 1}
>> Article.statuses.invert
=> { 0: close, 1: open}

したがって、下記のようにすれば変換できます。

>> Article.statuses.invert[1]
=> "open"

英語↔日本語

_i18nを使います。

英語→日本語

「モデル名.enumのカラム名の複数形_i18n」でハッシュが返ってきます。

>> Article.statuses_i18n
=> {"close"=>"非公開", "open"=>"公開"}

したがって、下記のようにすれば変換できます。

>> Article.statuses_i18n["open"]
=> "公開"

日本語→英語

先ほどと同様に、invertメソッドを使って英語→日本語の逆を利用します。

>> Article.statuses_i18n
=> {"close"=>"非公開", "open"=>"公開"}
>> Article.statuses_i18n.invert
=> {"非公開"=>"close", "公開"=>"open"}

したがって、下記のようにすれば変換できます。

>> Article.statuses_i18n.invert["公開"]
=> "open"

enumを表示する

説明の便宜上、インスタンス変数を使っていきます。

@article = Article.first

1.英語で表示

文字列で表示するだけなら、普通に

>> @article.status
=> "open"

でOKです。文字列ではなくシンボルがほしいなら、

>> @article.status.to_sym
=> :open

としてあげれば良いですね。

配列がほしい場合は、keysを使ってあげれば良いですね。

>> Article.statuses
=> { close: 0, open: 1}
>> Article.statuses.keys
=> ["close", "open"]

配列すらシンボルでほしいシチュエーションがあるとしたならこちら↓

>> Article.statuses.keys.map(&:to_sym)
=> [:close, :open]

2.日本語で表示

日本語化が済んでいれば、

>> @article.status_i18n
=> "公開"

でOKです。ビューではこれを一番使うのかなと思います。

配列が欲しい場合はあまりないかもしれませんが、valuesを使ってあげれば、出せます。

>> Article.statuses_i18n
=> {"close"=>"非公開", "open"=>"公開"}
>> Article.statuses_i18n.values
=> ["非公開", "公開"]

3.数字で表示

これがやっかいです。上記の「enumを変換する」を使って、

>> Article.statuses
=> { close: 0, open: 1}
>> Article.statuses[@article.status]
=> 1

のように書いてあげる必要があります。

before_type_castを使う方法もあるのですが、うまくいくときとそうでないときがあります。気になる方は下記読んでみてください。

こちらも、配列がほしい場合はあまりないかもしれませんが、valuesを使ってあげれば良いですね。

>> Article.statuses
=> { close: 0, open: 1}
>> Article.statuses.values
=> [0, 1]

enumをform_withで利用する

フォームでenumを選ばせる場合、ラジオボタンかセレクトボックスにする場合が多いのではないでしょうか。

その際、表示は日本語にしたいけど、コントローラにsubmitするデータとしては数字か英語で渡したい場合がほとんどだと思います。なお、今回のような設定だと、数字↔日本語の設定はしていないので、渡すデータは英語に限られます。

したがって、セレクトボックスに関して言えば、日本語→英語の変換を利用すれば良いわけですね。例えばこんな感じで。

= f.select :status, options_for_select(Article.statuses_i18n.invert), {include_blank: "選択してください"}, { class: "form-control"}

enumまとめ

enumの操作、という観点でまとめてみました。設定済の

  • 英語↔数字
  • 英語↔日本語

の変換(ハッシュの扱い)を覚えてしまえば、あとはいくらでも応用が効くと思うので、この記事がenumに悩まされるエンジニアやプログラミング学習者に届くと良いなと思います。

はるすと
はるすと

最後まで読んでくださってありがとうございました!

画像提供:Anja🤗#helpinghands #solidarity#stays healthy🙏によるPixabayからの画像

この記事を書いた人
こもれびエンジニア

自然と自由を愛するエンジニア。2021年1月に、大手製造業設計からプログラマ(Rails, AWS)へ転職。動物や自然との触れ合いや、汗を流すのが好き。

/HSP(繊細さん)/18デリケートな象/ストレングスファインダー(1分析思考/2親密性/3学習欲/4調和性/5収集心)、テニス、合気道、登山、あいだみつを、ジブリ、ワンピース、ドラゴンボール、AWS、Ruby on Rails、アイミング

twitterをフォローして、記事にならないちょっとした豆知識もチェック!
Rails・Webシステム開発
スポンサーリンク
SNSでシェア/コメントして、自分のアウトプット/発信力を高めるのにお使いください。 ↓ 各ページへジャンプ ↓
twitterをフォローして、記事にならないちょっとした豆知識もチェック!
スポンサーリンク
「そんなか」サイト

コメント

タイトルとURLをコピーしました