0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

[Rails]selectフォームにenumのリストを表示する2つの方法

Last updated at Posted at 2022-09-12

すんごい基礎的な内容なのですが、2通りのやり方に出会ったので整理したかったのと、地味なとこでハマったので備忘録。

やりたいこと

Postモデルにstatusというenumがあるとする。

class Post < ApplicationRecord
  enum status: { active: 10, inactive: 20 }, _prefix: true
end

これをこういう感じ↓で表示したい。
スクリーンショット 2022-09-12 12.09.04.png

htmlはこう。ブラウザで見える文字列とvalue属性を渡してあげたい。

<select class="form-control" name="post[status]" id="post_status">
  <option selected="selected" value="active">有効</option>
  <option value="inactive">非有効</option>
</select>

selectの出力にはRailsのselectメソッドを使う。
https://railsdoc.com/page/select

# f.object
f.select(メソッド名, 要素(配列 or ハッシュ)=nil, オプション={}, HTML属性={} or イベント属性={}, ブロック引数)

第二引数には以下のようなハッシュ、もしくは配列を渡してあげれば良い。

# { "ブラウザで見える文字列"=>"value属性" }
=> {"有効"=>"active", "非有効"=>"inactive"}

1. gemを使わず自分でメソッドを作るやり方

こちらを参照しました。gemを無闇に使いたくないならこれ。

config/locales
ja:
  activerecord:
    attributes:
      post/status:
        active: 有効
        inactive: 無効
view
<%= f.select(:status, Post.status_options, {}, class: 'form-control') %>
app/models/post.rb
  def self.status_options
    statuses.map { |k, _| [human_attribute_enum_value(:status, k), k] }.to_h
  end

  def self.human_attribute_enum_value(attr_name, value)
    human_attribute_name("#{attr_name}.#{value}")
  end

  def human_attribute_enum(attr_name)
    self.class.human_attribute_enum_value(attr_name, self[attr_name])
  end

2. gem使う。 "exnum"でやる。

exnumはこちら。
https://github.com/Kta-M/exnum#array-for-select-box-extention

Gemfile
gem 'exnum'

↓ここが地味にハマった。enumexnumにしないといけない。

app.models/post.rb
  exnum status: { active: 10, inactive: 20 }, _prefix: true
config/locales/
ja:
  activerecord:
    enum:
      post:
        status:
          active: 有効
          inactive: 非有効

ここまですると以下のようなメソッドが使える。

[1] pry(main)> Post.statuses_i18n
=> {"active"=>"有効", "inactive"=>"非有効"}

[2] pry(main)> Post.statuses_i18n.invert
=> {"有効"=>"active", "非有効"=>"inactive"}

[3] pry(main)> Post.statuses_for_select
=> [["有効", "active"], ["非有効", "inactive"]]

これ↑の1だとブラウザで見える文字列とvalue属性が逆になっちゃうので、2か3をselectの引数に渡してあげればOK。

view
<%= f.select(:status, Post.statuses_i18n.invert, {}, class: 'form-control') %>

どっちにするんだい!?

modelに色々メソッドとか書きたくないので、gem使う方に一票。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?