#はじめに
enumに触れたので知識を深める。
#enumとは
ActiveRecordの提供するモジュールの1つ。値がデータベース内の整数にマップされる列挙型属性を宣言し、名前で照会できる。
#メリット/デメリット
###メリット
- データベースに保存されるデータサイズが小さく済むため、処理速度が速い。
- 定数名を変更したい時に改修が簡単
###デメリット
- データベース側では数値を保存しているため、何を表しているかが分からない。
#enumの設定方法
enum カラム名: { 定数1: 数値1, 定数2: 数値2, }
この時、指定するカラムはintegerであることに注意する。
今回は「postsテーブル」にある「genreカラム」と「contentカラム」を例に取る。
create_table :posts do |t|
t.integer :genre
t.text :content
t.timestamps
end
###カラムにenumを設定
今回は属性とデータベース整数の関係をハッシュで明示的にマッピングを行う。
class Post < ApplicationRecord
#省略
#ハッシュ形式でenumを設定
enum genre: {
others: 0,
html: 1,
css: 2,
js: 3,
ruby: 4,
rails: 5
}
end
配列を使用する場合、値からデータベース整数への暗黙的なマッピングは、値が配列に表示される順序から派生することに注意。
class Post < ApplicationRecord
# 配列で指定した場合
enum genre: [ :others, :html, :css, ... ]
end
列挙型配列に値を追加したら、配列内のその位置を維持する必要があり、新しい値は配列の最後にのみ追加する必要がある。
未使用の値を削除するには明示的なハッシュ構文を使用する必要がある。
###確認
コンソールを起動して、出力結果を確かめる。
# インスタンス生成から数値or定数名で指定
Post.create!(genre: 1, content: "これはHTMLです。")
Post.create!(genre: "html", content: "これはHTMLです。")
=> #<Post id: 1, genre: "html", content: "これはHTMLです。", created_at: "省略", updated_at: "省略">
=> #<Post id: 2, genre: "html", content: "これはHTMLです。", created_at: "省略", updated_at: "省略">
# 存在しない場合は ArgumentError
Post.create!(genre: "HTML", content: "存在しません")
=> #ArgumentError ('HTML' is not a valid genre)
# マッチする条件を数値or定数名で指定
Post.find_by(genre: 1)
post = Post.find_by(genre: "html")
post.genre
#=> "html"
post.genre_before_type_cast
#=> 1
post.html?
#=> true
post.css?
#=> false
Post.genres
#=> {"html"=>1, "css"=>2, "js"=>3, "ruby"=>4, "rails"=>5}
Post.genres[:css]
#=> 2
今回のenumをハッシュ形式で設定したものは、セレクトボックスと併用することで便利にプルダウンを実装する方法で学んだ。
参考もと
Rails API/ActiveRecord :: Enum
【Rails】Enumってどんな子?使えるの?
Railsガイド/Active Record クエリインターフェイス
【Rails・ActiveRecord】_before_type_castを使って型が変換される前の値にバリデーションをかける