ActiveHash(アクティブハッシュ)
ActiveHashとは、モデルファイル内に直接記述することで、データベースへ保存せずにデータを取り扱うことができるGemです。
モデルファイルに直接記述したデータに対して、ActiveRecordのようなメソッドを用いることができます。
例えば、都道府県名一覧やカテゴリーなど「基本的に変更されないデータ」を扱うときに便利です。
ここでは例として商品の送り元住所の都道府県登録にActiveHashを用います。
ActiveHashの導入
Gemfileの最下部に
gem 'active_hash'
を追記し、bundle install
を実行します。
モデルの作成
Itemモデルを作成します。
次に、都道府県名を管理するPrefectureモデル(厳密にはActiveHashを用いたクラス)を作成します。
データベースを利用しないため、手動で
app/modelsディレクトリ内にprefecture.rbを作成します。
まずは、モデルの「Prefectureクラス」を定義し、ActiveHash::Baseクラスを継承します。
次に、都道府県名のデータは、配列にハッシュ形式で格納します。
app/models/prefecture.rb
class Prefecture < ActiveHash::Base
self.data = [
{ id: 1, name: '---' }, { id: 2, name: '北海道' }, { id: 3, name: '青森県' },
{ id: 4, name: '岩手県' }, { id: 5, name: '宮城県' }, { id: 6, name: '秋田県' },
{ id: 7, name: '山形県' }, { id: 8, name: '福島県' }, { id: 9, name: '茨城県' },
{ id: 10, name: '栃木県' }, { id: 11, name: '群馬県' }, { id: 12, name: '埼玉県' },
{ id: 13, name: '千葉県' }, { id: 14, name: '東京都' }, { id: 15, name: '神奈川県' },
{ id: 16, name: '新潟県' }, { id: 17, name: '富山県' }, { id: 18, name: '石川県' },
{ id: 19, name: '福井県' }, { id: 20, name: '山梨県' }, { id: 21, name: '長野県' },
{ id: 22, name: '岐阜県' }, { id: 23, name: '静岡県' }, { id: 24, name: '愛知県' },
{ id: 25, name: '三重県' }, { id: 26, name: '滋賀県' }, { id: 27, name: '京都府' },
{ id: 28, name: '大阪府' }, { id: 29, name: '兵庫県' }, { id: 30, name: '奈良県' },
{ id: 31, name: '和歌山県' }, { id: 32, name: '鳥取県' }, { id: 33, name: '島根県' },
{ id: 34, name: '岡山県' }, { id: 35, name: '広島県' }, { id: 36, name: '山口県' },
{ id: 37, name: '徳島県' }, { id: 38, name: '香川県' }, { id: 39, name: '愛媛県' },
{ id: 40, name: '高知県' }, { id: 41, name: '福岡県' }, { id: 42, name: '佐賀県' },
{ id: 43, name: '長崎県' }, { id: 44, name: '熊本県' }, { id: 45, name: '大分県' },
{ id: 46, name: '宮崎県' }, { id: 47, name: '鹿児島県' }, { id: 48, name: '沖縄県' }
]
end
マイグレーションファイルを編集
itemsテーブルのカラムにprefecture_id
を追加します。
ターミナル
% rails db:migrate
を実行します。
アソシエーションを設定
Itemモデルのアソシエーションを設定
Itemモデルにはbelongs_toを設定します。
ActiveHashを用いて、belongs_to
を設定するには、
extend ActiveHash::Associations::ActiveRecordExtensions
と記述してmoduleを取り込みます。
app/models/item.rb
class Article < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :prefecture
end
Prefectureモデルのアソシエーションを設定
Prefectureモデルにはhas_many
を設定します。
ActiveHashを用いて、has_many
を設定するには、
include ActiveHash::Associations
と記述してmoduleを取り込みます。
prefecture.rbに以下を追記しましょう。
app/models/prefecture.rb
class Prefecture < ActiveHash::Base
self.data = [
# 省略
]
include ActiveHash::Associations
has_many :items
end
バリデーションを設定
app/models/item.rb
class Article < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :prefecture
validates :prefecture_id, numericality: { other_than: 1 }
numericality
で、数値かどうかを検証しています。
またother_than: 1
でid: 1
以外であれば保存できるように設定しています。
今回は「---」のidが1なので、このように記述しています。
登録フォームにプルダウン形式で表示
フォーム内に以下の記述を追加します。(他の部分は省略しています)
app/views/item/new.html.erb
<%= f.collection_select(:prefecture_id, Prefecture.all, :id, :name, {}) %>
collection_selectを用いることで、データをプルダウン形式で表示しています。
引数は以下のように指定します。
<%= form.collection_select(保存するカラム名, オブジェクトの配列, カラムに保存する項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>
今回はオプションを指定しないため{}
としています。