#はじめに
アンケートなんかでよく見かける、都道府県をプルダウンから選択させる機能。、form_withメソッドを使用して投稿する機能をもたせることができる。しかし、その都道府県はテーブル上では数値で管理されている方が使い勝手がよい。数値で管理できるようにするには、予め、都道府県名とそれに紐づく数字を用意しておく必要がある。そのようなときに便利な機能が、ActiveHashである。
##ActiveHashとは
基本的に変更することのないデータをモデル内に記入することで、データベースへ保存せずにデータを取り扱うことができるようになるGem。主に、ビューで、プルダウンメニューとして表示させたいときに使う。
公式ドキュメントはこちら
##準備の流れ
1. Gemの記述
2. Gemをインストール
3. モデルを生成
###1. Gemの記述
ファイルのいちばん下の行でOK
gem 'active_hash'
###2. Gemをインストール
% bundle install
###3. モデルを生成
% rails g model モデル名 --skip-migration
モデル名には、プルダウンメニューを一括りにするような名前が望ましい。
ex)野球、サッカー、テニス…
のようなプルダウンを作成する場合は、モデル名はsport
となる。
--skip-migrationオプション
をつけることで、マイグレーションファイルを生成しなくなる。ActiveHashはデータベースに保存しないので、マイグレーションファイルを必要としない。
以後、スポーツのプルダウンメニューを例に説明する。
##記述から表示までの流れ
4. クラスを定義し継承する
5. プルダウンメニューの項目を記述
6. アソシエーションを記述
7. バリデーションを記述
8. プルダウンメニューを表示
###4. クラスを定義し継承する
「3. モデル生成」で作られたモデルを以下の記述に変更する。
class Sport < ActiveHash::Base
self.data = []
end
ActiveHash::Baseを継承することで、ActiveRecordのメソッドが使用できる。
###5. プルダウンメニューの項目を記述
プルダウンの中身は、配列にハッシュで入れる。
class Sport < ActiveHash::Base
self.data = [
{ id: 1, name: '---' },
{ id: 2, name: 'Baseball' },
{ id: 3, name: 'Soccer' },
{ id: 4, name: 'Tennis' }
]
end
###6. アソシエーションを記述
以下、すでに、別の投稿したものを保存するテーブルが存在する前提の説明。
class Post < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to_active_hash :sport
end
extend ActiveHash::Associations::ActiveRecordExtensions
の記述によって、 belongs_to_active_hashメソッド
が使えるようになる。
sportモデルにアソシエーションの記述の必要はない。
※通常のアソシエーションと記述が異なる点に注意
###7. バリデーションを記述
class Post < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to_active_hash :sport
validates :sport_id, presence: true #空の投稿を保存できない
validates :sport_id, numericality: { other_than: 1 }
#プルダウンの選択が「--」の時は保存できない
end
###8. プルダウンメニューを表示
####collection_selectメソッド
collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション)
collection_select(:sport_id, Sport.all, :id, :name, {}, {class:"sport-select"})
保存されるカラム名:テーブルのどのカラムに保存をするのか。
オブジェクトの配列:配列のハッシュ全て表示させる場合は、.all
でOK
カラムに保存される項目:app/models/sport.rb
の中で、id:
としていた部分を、カラムに保存させたい
選択肢に表示されるカラム名:プルダウンでapp/models/sport.rb
のname:
としていた部分を表示させる
オプション:必要に応じて
htmlオプション:クラス名など
##最後に
とにかく、collection_selectメソッドの引数が多すぎて、混乱しそう…