Ruby
Rails
初心者
select
Option

Rails プルダウン selectのoptionをグループ化する

はじめに

入力フォームやサーチフォームがある画面の作成に欠かせないプルダウン
とても便利で使い勝手がいいのですが、要素が多くなると一気に見辛く感じますよね?
今回はselectのoptionをグループ化してプルダウンの中身にインデックスをつけるメソッドの使い方を説明します。

どういうこと?

言葉では説明しにくいんですよね...
とりあえず見てください。
これを
スクリーンショット 2018-02-14 19.55.36.png
こうします。
スクリーンショット 2018-02-14 19.56.07.png

実装

テーブル定義

今回の例ではteamsmembersの2テーブルを使用します。
teams

id name
1 あんこうチーム
2 カメさんチーム
... ...

members

id team_id name
1 1 西住 みほ
2 1 武部 沙織
... ... ...

team対memberが1対多です。

モデル

上記の2テーブル分のモデルを用意します。

team.rb
class Team < ApplicationRecord
  has_many :members
end
member.rb
class Member < ApplicationRecord
end

teamにはリレーションを設定しています。
team対memberが1対多なのでhas_manyです。

ビュー

さて、ここが本丸です。
使用するメソッドはgrouped_collection_selectです。
http://railsdoc.com/references/grouped_collection_select

<%= form_for @user, url: {action: 'update'} do |f| %>

  <%= f.grouped_collection_select(:member_id, Team.all, :members, :name, :id, :name) %>

<% end %>

結果

簡単に実装できるんですねー。すごーい。

<form action="/user/update" method="post">
  <select name="test[member_id]">
    <optgroup label="あんこうチーム">
      <option value="1">西住 みほ</option>
      <option value="2">武部 沙織</option>
      <option value="3">五十鈴 華</option>
      <option value="4">秋山 優花里</option>
      <option value="5">冷泉 麻子</option>
    </optgroup>
    <optgroup label="カメさんチーム">
      <option value="6">角谷 杏</option>
      <option value="7">小山 柚子</option>
      <option value="8">河嶋 桃</option>
    </optgroup>
    <optgroup label="アヒルさんチーム">
      <option value="9">磯辺 典子</option>
      <option value="10">近藤 妙子</option>
      <option value="11">河西 忍</option>
      <option value="12">佐々木 あけび</option>
    </optgroup>
    <optgroup label="カバさんチーム">
      <option value="13">カエサル</option>
      <option value="14">エルヴィン</option>
      <option value="15">左衛門佐</option>
      <option value="16">おりょう</option>
    </optgroup>
    <optgroup label="ウサギさんチーム">
      <option value="17">澤 梓</option>
      <option value="18">山郷 あゆみ</option>
      <option value="19">丸山 紗希</option>
      <option value="20">阪口 桂利奈</option>
      <option value="21">宇津木 優季</option>
      <option value="22">大野 あや</option>
    </optgroup>
    <optgroup label="カモさんチーム">
      <option value="23">そど子</option>
      <option value="24">ゴモヨ</option>
      <option value="25">パゾ美</option>
    </optgroup>
    <optgroup label="レオポンさんチーム">
      <option value="26">ナカジマ</option>
      <option value="27">スズキ</option>
      <option value="28">ホシノ</option>
      <option value="29">ツチヤ</option>
    </optgroup>
    <optgroup label="アリクイさんチーム">
      <option value="30">ねこにゃー</option>
      <option value="31">ももがー</option>
      <option value="32">ぴよたん</option>
    </optgroup>
  </select>
</form>

引数についての補足

こちらがリファレンスにある引数の指定方法です。
f.grouped_collection_select(プロパティ名, オブジェクトの配列, タグを取得するメソッド, タグのラベル, valueの項目, テキストの項目 [, オプション])
理解できますか?できるあなたはRailsに精通してる人です!
初心者にはちょっと引数の意味が分かり辛いので説明します。

プロパティ名

プルダウンで選択した値を保存したいカラムの名前です。
今回の例では保存時にusers.member_idにプルダウンで選択した値が入ります。

オブジェクトの配列

インデックスとして表示したい要素の配列です。
今回の例ではチーム名をインデックスとして表示したいのでTeam.allを設定しています。

タグを取得するメソッド

ここが一番分かり辛いと思います。タグってなんやねん。
とにかくここはインデックス以下に表示する普通のoptionを取得するメソッドを指定します。
注意すべき点はこのメソッドはオブジェクトの配列に対するメソッドだということです。
今回の例では、Team.allに対するメソッドということになります。
Team.allから紐づくmemberの一覧を取得するとなると、

teams = Team.all
members = teams.members

ですよね?
なので、この引数にはmembersを設定しています。

タグのラベル

これは「オブジェクトの配列」で渡したオブジェクトのどのカラムをインデックスにするかという引数です。
今回の例では、teams.nameを表示したいのでnameを設定しています。

valueの項目

これは「タグを取得するメソッド」で取得したオブジェクトのどのカラムをoptionvalueにするかという引数です。
今回の例では、members.idvalueにしたいのでidを設定しています。

テキストの項目

これは「タグを取得するメソッド」で取得したオブジェクトのどのカラムをoptionの表示名にするかという引数です。
今回の例では、members.namevalueにしたいのでnameを設定しています。

おわりに

意外と手軽に使える上に便利です。
みなさん使って見てはいかが?(もう使ってるか...)
ていうかあんこうチームだけ「さん」ついてないんですね。
確かにアンコウさんチームって聞いたことないわ。

ブログで見たい人はこちら -> Rails プルダウン selectのoptionをグループ化する