Simple gadget life programming diary

Simple gadget life の中の人によるプログラミングメモ

railsでhas manyオブジェクトをViewで編集する方法

ネストされたオブジェクトの中身を画面表示する。
has_manyで紐付いているオブジェクトの中身を表示する方法がわからなかったのでメモ。

モデルの構成は以下のとおり。

class Event < ActiveRecord::Base
  # attr_accessible :title, :body
  attr_accessible :title, :memo, :image_attributes, :sub_events_attributes
  
  has_one :image, class_name: "EventPicture", dependent: :destroy
  has_many :sub_events , dependent: :destroy

  accepts_nested_attributes_for :image, allow_destroy: true
  accepts_nested_attributes_for :sub_events, allow_destroy: true
end


class SubEvent < ActiveRecord::Base
  # attr_accessible :title, :body
  attr_accessible :event, :time, :content, :index

  belongs_to :event
end

eventオブジェクトの下にはhas_manyで複数のsub_eventが紐付いている。

これをViewで表示するためにはfields_forメソッドを使用する。
View側の処理は以下の通り。

<% @page_title = "イベントの編集" %>

<h1><%= @page_title %></h1>
<p><%= link_to "イベントに戻る" , @event %></p>

<%= form_for @event, html: {multipart: true} do |form| %>
<%= render "form", form: form %>
<p><%= form.submit %></p>
<% end %>

実際はformのヘルパで処理を実施。

<% @page_title = "新規・編集をするよ" %>

<h1><%= form.label :title, "タイトル" %></h1>
<h1><%= form.text_field :title %></h1>

<!-- #mergeはハッシュの統合。optionが不要な場合は{}(からの配列)を設定させる。 -->

<%= form.fields_for :image do |imgf| %>
  画像のアップロード<br>
  <%= imgf.file_field :uploaded_image %>
  <% if !imgf.object.new_record? && imgf.object.errors.empty? %>
    <%= event_image_tag @event, width: 600 %>
    <%= imgf.check_box :_destroy %>
    <%= imgf.label "削除する" %>
    <%= imgf.hidden_field :id %>
  <% end %>
<% end %>

<table class= "subevent">
  <tr>
    <th><%= form.label :time, "所要時間" %></th>
    <th>内容</th>
  </tr>
  <%= form.fields_for :sub_events, form.object.sub_events do |sevf| %>
    <% if sevf.object.errors.empty? %>
      <tr>
        <td><%= sevf.text_field :time %></td>
        <td><%= sevf.text_field :content %></td>
        <%= sevf.hidden_field :index %>
      </tr>
    <% end %>
  <% end %>
</table>

<%= form.label :memo, "メモ" %>
<%= form.text_field :memo %>

<%= form.fields_for :sub_events, form.object.sub_events do |sevf| %>
この部分でevent配下のsubeventオブジェクトを1つずつ取得しsevfへ代入している。
(表示するカラムと受け渡すオブジェクトを指定)
その後はオブジェクトが1つの場合と同様に処理を記載していく。