概要
システムを構築してると、幾つかのステータスを持つことがあります。例えば、商品についてのモデルProduct
のstatus
として、「発売予定」「発売中」「絶版」「再販未定」の4つのステータスを持っているとします。
これらを扱うModelの良い書き方を紹介します。
普通にやることの問題点
それぞれのステータスを10, 20, 30, 40という数値で管理しようと思います。1
そのとき単にinteger型のフィールドにすると、例えば、発売中にステータスをフォームは
<%= form_for @product do |f| %> <%= f.label :status %> <%= f.radio_button :status, 10 %> 発売予定 <%= f.radio_button :status, 20 %> 発売中 <%= f.radio_button :status, 30 %> 絶版 <%= f.radio_button :status, 40 %> 再販未定 <% end %>
となったり、
app/models/product.rb
def in_sale? self.status == 20 end
となるなど、ここだけでは意味が分からない数値が入って可読性が悪くなってしまいます。
それを防ぐための機能としてRailsのModelにはEnumという機能が用意されています。
Enumの使い方
Modelに以下のように書きます。
class Product < ActiveRecord::Base enum status: {will_be_released: 10 ,in_sale: 20, sold_out: 30, resale_undecided: 40} end
このように定義してやると、DBの値は10,20,30,40のままで、コード内では:will_be_released
などで参照できます。
たとえば、先ほどのViewのコードは以下のように書くことができます。
<%= form_for @product do |f| %> <%= f.label :status %> <%= f.radio_button :status, :will_be_released %> 発売予定 <%= f.radio_button :status, :in_sale %> 発売中 <%= f.radio_button :status, :sold_out %> 絶版 <%= f.radio_button :status, :resale_undecided %> 再販未定 <% end %>
このようにしてやれば、無意味な数値がコードに入らないのでよみやすくなります。
また、ふたつ目のin_sale?
メソッドについてですが、実はeunmを定義した時点で自動的に作成されます。同様にstatus
を:in_sale
に更新するメソッドとしてin_sale!
も作成されています。
また、:will_be_released
, :in_sale
, :sold_out
, :resale_undecided
以外の値を代入すると、エラーが発生するため、DB自体にConstraintを設定することなく、データの整合性も保つことができます。
まとめ
ModelのEnumを使うことで、得られる主なメリットは可読性の工場ですが、様々な便利なメソッドが用意されたり、DBの設定を変更しなくても保存可能な値を増やせたりします。
また、enum_help
というGemを代入することで多言語対応も可能です。
このような保存する値が決まっているものに関しては積極的にEnumを作っていきましょう。
- 今回、それぞれの判別用の数字を10, 20, 30, 40としましたが、このように10飛びに、あるいは100飛びにすることによって、15のように間に値を数値入れることができます。 ↩
コメントを残す