Rails つまみぐい

Rails つまみぐい

Ruby on Rails 初学者による行き当たりばったりなメモ

プルダウンメニュー(select_tag)の中身をデータベースに用意する


プルダウンメニュー(select_tag)の選択肢を決め打ちでやらず、マスタとしてDB内のテーブルに用意する場合のやり方です。collection_select を使います。

ここでは例として、都道府県名を格納するために prefecture テーブルと Prefecture モデルを作成します。

|id  |name   |
|   1|北海道    |
|   2|青森県    |
|   3|岩手県    |
...(以下省略)

このテーブルの中身をプルダウンメニューの選択肢として利用するには以下のように書きます。

<%= form_for @user do |f| %>
  <%= f.label :prefecture_id %>
  <%= f.collection_select :prefecture_id, Prefecture.all, :id, :name %>
<%- end -%>


文法としてはこんな感じで、それぞれの引数の意味は以下の通りです。

<%= f.collection_select (1), (2), (3) , (4) [, オプション] %>
(1) 属性名 フォームの対象モデルの中の該当する属性名(ここでは User.prefecture_id)
(2) 配列データ プルダウンメニューの選択肢に使用するデータ配列
各要素は連想配列やオブジェクトなど
(3) カラム名 プルダウンメニューで値として扱うカラムの名前
(4) 表示名カラム名 プルダウンメニューで表示名として扱うカラムの名前




ちなみに同じことを select タグでやるとこんな感じでできます。

<%= f.select :prefecture_id, Prefecture.all.map{|pf| [pf.name, pf.id]} %>

あんまり変わらないやんって思った方、正解です(^^)

オプションあれこれ

プルダウンメニューの先頭に空白行を追加する(:include_blank オプション)

プルダウンメニューの選択肢の先頭に空白の選択肢を追加することができます。一旦どれかを選択しても、未選択の状態に戻せるということです。なお、空白行の value は空文字列が指定されます。

<%= f.collection_select
      :prefecture_id, Prefecture.all, :id, :name, :include_blank => true %>

include_blank オプションの値を true/false ではなく文字列にすると、その文字列が使用されます。

<%= f.collection_select
      :prefecture_id, Prefecture.all, :id, :name,
      :prompt => "選択を解除" %>


値が未設定の時にプロンプトを表示(:prompt オプション)

prompt オプションを使うと、プルダウンメニューが選択されていない時(=初期値が設定されなかったとき)に「選択して下さい」といった文字列の行が先頭に追加されます。

<%= f.collection_select
      :prefecture_id, Prefecture.all, :id, :name,
      :prompt => true %>

表示される文字列は I18n を使っている場合、ロケ―ルファイルで指定された文字列が使用されます。

ja:
  helpers:
    select:
      prompt: "選択してね♪"


promptオプションの値を true/false ではなく文字列にすると、それがプロンプトとして使用されます。

<%= f.collection_select
      :prefecture_id, Prefecture.all, :id, :name,
      :prompt => "好きなものを選んで" %>


include_blank オプションと prompt オプションはどちらも先頭行に追加しますが、動作がちょっとだけ違います。

:include_blank 常に先頭行を追加
:prompt 選択行の指定がない時だけ先頭行を追加


デフォルトの選択を指定する(:selected オプション)

やりかたは通常の f.select と同じで

<%= f.collection_select
      :prefecture_id, Prefecture.all, :id, :name, :selected => 13 %>

と書けます。

が、あまりこのオプションはあまり使わないでしょう。

selected を指定しなくても、@user.prefecture_id に値が既に入っている場合は自動的にその値にセットされます。逆に selected を使うと、常に selected で指示されたものが選択されることになります。初期値として入れたい場合は、controller の new メソッド内で初期値を設定した方がいいでしょう。

class UserController < ApplicationController
  def new
    @user = User.new(:prefecture_id => 13)
  end
end