2013年5月8日水曜日

Formで指定したmodel以外のmodelを指定してコンボボックスを生成するサンプル


上図のようなmodelの構造で、DouroFusetsuの更新画面を考えてみる。

まずはscaffold。(実行結果は省略。)
rails generate scaffold douro_fusetsu shichoson:references douro:references
デフォルトの状態の画面では、下図のように型をreferencesにして作成したmodelクラスのハッシュを入力しなければならないので、


コンボボックスでIDを選択できるように、下図のように変更する。


View側のソースは下記のようになる。
<%= form_for(@douro_fusetsu) do |f| %>
  <% if @douro_fusetsu.errors.any? %>
    <div id="error_explanation">
      <h2><%= pluralize(@douro_fusetsu.errors.count, "error") %> prohibited this douro_fusetsu from being saved:</h2>

      <ul>
      <% @douro_fusetsu.errors.full_messages.each do |msg| %>
        <li><%= msg %></li>
      <% end %>
      </ul>
    </div>
  <% end %>

  <div class="field">
    <%= f.label :shichoson %><br />
    <%= f.collection_select(:shichoson_id, Shichoson.find(:all), :id, :name) %>
  </div>
  <div class="field">
    <%= f.label :douro %><br />
    <%= f.collection_select(:douro_id, Douro.find(:all), :id, :name) %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>
市町村では、選択肢の数が多すぎる(日本全国で1742もある)ので、都道府県を選択して数を絞り込めるようにしたい。

TodofukenとShichosonは親子関係であるものの、DouroFusetsuはTodofukenと直接関係がないので、f.collection_selectは使うことができない。

その代わりに、下記のように、f.をつけずにcollection_selectを使うことにする。
<%= collection_select(:douro_fusetsu, "todofuken_id", Todofuken.find(:all), :id, :name) %>
しかしながらエラーが表示されてしまう。


f.がついていなくても、formの名前が同じ場合は、form_forで関連づけられているmodelのメンバーではないということでエラーになってしまうようだ。

下記のように、シンボル:douro_fusetsu ではなく、まったく別の名前を指定すると、
<%= collection_select("help", "todofuken_id", Todofuken.find(:all), :id, :name) %>
エラーが出ずに表示されるようになった。


0 件のコメント:

コメントを投稿