目次
この記事はアピリッツの技術ブログ「DoRuby」から移行した記事です。情報が古い可能性がありますのでご注意ください。
railsのModelで列挙型を扱うのに、gemのenumerizeが便利です。
enumerizeについて、幾つかの使い方を紹介したいと思います
■ gem
gem ‘enumerize’
■ モデル
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, in: [:male, :female] #配列
enumerize :role, in: {:user => 1, :admin => 2} #ハッシュ
end
これだけでsexに対するinclusionのバリデーションがかかる
エラーメッセージ
性別は一覧にありません。
■ ja.yml
ja:
enumerize:
user:
sex:
male: 男
female: 女
role:
user: 会員
admin: 管理者
■ 使い方
User.sex.values # => ["male", "female"]
User.sex.options # => [["男", "male"], ["女", "female"]]
※もしフィールド名はnameの場合、User.nameはUserモデルのメソッドのため、enumerized_attributesを利用する
User.name # => "User"
User.enumerized_attributes[:sex].values # => ["male", "female"]
User.enumerized_attributes[:sex].values # => [["男", "male"], ["女", "female"]]
user = User.new
user.male? # => false
user.female? # => false
user.sex = 'male'
user.male? # => true
user.female? # => false
user.sex_value # => "male"
user.sex_text # => "男"
user.role = :user
user.role #=> 'user'
user.role_value #=> 1
user.role_text #=> "会員"
User.role.find_value(:user).value #=> 1
User.role.find_value(:admin).value #=> 2
■ form_for
<%= form_for @user do |f| %>
<%= f.select :sex, User.sex.options %>
<% end %>
■ SimpleForm
select collection
<%= simple_form_for @user do |f| %>
<%= f.input :sex %>
<% end %>
radio buttons
<%= simple_form_for @user do |f| %>
<%= f.input :sex, :as => :radio_buttons %>
<% end %>
■ enumerizeを使用する際、モデルのdefault値
マイグレートファイルでdefaultを指定していたとしても、モデルでenumerizeのdefaultを指定しないとnullが挿入される。
enumerize :role, in: [:user, :admin], default: :user
■ ActiveRecord scopes
scope: trueを利用して、scopeとして利用できる。
class User < ActiveRecord::Base
extend Enumerize
enumerize :sex, :in => [:male, :female], scope: true
enumerize :status, :in => { active: 1, blocked: 2 }, scope: :having_status
end
User.with_sex(:female)
# SELECT "users".* FROM "users" WHERE "users"."sex" IN ('female')
User.without_sex(:male)
# SELECT "users".* FROM "users" WHERE "users"."sex" NOT IN ('male')
User.having_status(:blocked).with_sex(:male, :female)
# SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')