目的
Railsで作成したアプリにプルダウンリストを追加する。
開発環境
macOS: Big Sur
Rubyバージョン: 2.6.5
Railsバージョン: 6.0.0
前提
- アプリを立ち上げ済み。
手順
前置き
都道府県名一覧などの「基本的に変更されないデータ」
は、データベースに保存する必要性がありません。
また、ビューファイルに直接書く方法もありますが可読性に欠けてしまいます。
そのようなケースでは、ActiveHash
が有用です。
Active_Hash
とは、モデルファイル内に直接記述したデータを、データベースへ保存することなく取り扱うことができるGemの事です。
これを用いることで、モデルファイル内に記述したデータに対して、ActiveRecordのようなメソッド(allやcreateメソッド)を用いることができます。
今回は商品(Item)と商品がどこにあるか(Prefecture)という関係があった場合を仮定し、進めていきます。
内容としては、プルダウンリストで都道府県が選択できるところまでを記載します。
細かいビューなどは省略しますので、各自編集をお願いします。
ActiveHashのインストール
それでは早速始めていきましょう!
ますActiveHashをインストールします。
# 省略
gem 'active_hash'
bundle install
モデルの作成
今回のアプリでは、商品を管理するItemモデルと、商品の場所(都道府県)を管理するPrefectureモデルを作成します。
都道府県を管理するモデルは、ActiveHashを用いて管理していきます!
まず下記コマンドを実行して、Itemモデルを作成します!
% rails g model item
続いて、app/modelsディレクトリ配下にprefecture.rb
を手動で作成します。
Prefectureモデルへデータを定義
次にプルダウンリストの作成です!
ここで少し説明ですが、モデルの「Prefectureクラス」を定義し、ActiveHash::Base
クラスを継承する必要があります。
ActiveHash::Base
とは、ActiveHashを用いる際に必要となるクラスです。
このクラスを継承することで、ActiveRecordと同じようなメソッドを使用できるようになります!
本題に戻って、以下のようにプルダウンリストを作成していきましょう!
class Prefecture < ActiveHash::Base
self.data = [
{ id: 1, name: '--' },
{ id: 2, name: '北海道' },
{ id: 3, name: '青森県' },
{ id: 4, name: '岩手県' },
{ id: 5, name: '宮城県' },
# 中略
]
end
この記述で、PrefectureモデルにActiveHash::Base
を継承することができ、
都道府県のデータに対して、ActiveRecordのようなメソッドが使用できるようになりました!
マイグレーションファイルの編集
続いてマイグレーションファイルの編集です。
class CreateItems < ActiveRecord::Migration[6.0]
def change
create_table :items do |t|
t.string :title , null: false
t.text :text , null: false
t.integer :prefecture_id , null: false
t.timestamps
end
end
end
今回は商品に紐付く都道府県を表示させる方法も紹介します。
そのためにprefecture_id
という名前のカラムを作成します。
編集後は下記コマンドでデータベースに反映しましょう!
% rails db:migrate
アソシエーションの追加
商品と紐付いた都道府県を取得できるように、ItemモデルとPrefectureモデル間でアソシエーションを設定しておきます!
ActiveHashを用いてアソシエーションを設定する場合は、ActiveHashで定義されているmodule
をモデルに取り込む必要があります。
module
とは、特定の役割を持つメソッドや定数に名前を付けてまとめたものです。
では、実際にActiveHashを用いたアソシエーションを設定していきましょう!
Itemモデルのアソシエーションを設定
商品は1つの都道府県に紐付いています。そのため、Itemモデルにはbelongs_toを設定します。
ActiveHashを用いて、belongs_toを設定するには、
extend ActiveHash::Associations::ActiveRecordExtensions
と記述してmoduleを取り込みます!
class Item < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :prefecture
end
これで、ActiveHashを用いてのbelongs_toが設定できました!
Prefectureモデルのアソシエーションを設定
続いて都道府県です!
1つの都道府県はたくさんの商品に紐付いています。そのため、Prefectureモデルにはhas_manyを設定します。
ActiveHashを用いて、has_manyを設定するには、
include ActiveHash::Associations
と記述してmoduleを取り込みます!
class Prefecture < ActiveHash::Base
self.data = [
{ id: 1, name: '--' },
{ id: 2, name: '北海道' },
{ id: 3, name: '青森県' },
{ id: 4, name: '岩手県' },
{ id: 5, name: '宮城県' },
# 中略
]
include ActiveHash::Associations
has_many :items
end
以上でアソシエーションを設定できました!
バリデーションの設定
次にバリデーションの設定をしていきます!
プルダウンリストのカラム型はinteger
なので、numericality
を使い設定してきます!
class Item < ApplicationRecord
extend ActiveHash::Associations::ActiveRecordExtensions
belongs_to :prefecture
#中略
#都道府県の選択が「--」の時は保存できないようにする
validates :prefecture_id, numericality: { other_than: 1 }
end
これで、「数値であること」&「id: 1以外」
という条件での保存が許可されるバリデーションが設定できました!
「id: 1以外」という条件は都道府県のid1が「--」
という何も選択していないという意味だからです。
プルダウンリストの表示
最後にプルダウンリストの表示の仕方を記述します!
以下のような記述で表示が可能です!
<%= form.collection_select(保存されるカラム名, オブジェクトの配列, カラムに保存される項目, 選択肢に表示されるカラム名, オプション, htmlオプション) %>
引数 | 値 | 役割 |
---|---|---|
保存されるカラム名 | :prefecture_id | 保存先のカラム名 |
オブジェクトの配列 | Prefecture | 配列データの指定 |
カラムに保存される項目 | id | 参照するDBのカラム名 |
選択肢に表示されるカラム名 | name | 実際に表示されるカラム名 |
オプション | {} | 今回は指定なし |
htmlオプション | {class:"prefecture-select"} | 今回はCSSのクラス名を付与 |
<%= f.collection_select(:prefecture_id, Prefecture.all, :id, :name, {}, {class:"prefecture-select"}) %>
今回の場合ですとこのように記述することで実装出来ます!
最後に
以上で、プルダウンリストの実装ができたと思います。
あとは各自、ルーティングの設定やビューファイルの編集などしてください。
では。