のぶLab.

流しのソフトウェアエンジニアの雑記帳. Android, Scala, Clojure, Ruby on Railsなど

Railsで1:Nのテーブルを扱う

Gemの導入

Gemfileに以下を追加してnested form gem を導入

gem"nested_form"

bundle install

フォーム要素を動的に追加するためのプラグインを追加

application.jsに以下を追加

//= require jquery_nested_form

使ってみる

view
<%= nested_form_for @project do |f|%>
    <%= f.fields_for :tasks do |task_form| %>
        <%= task_form.text_field :name %>
        <%= task_form.link_to_remove "Remove Task" %>
    <% end %>
    <p><%= f.link_to_add "Add Task", :tasks %></p>
<% end %>

"nested_form_for"を使わないと"link_to_remove"や"link_to_add"が使えないようなので注意

controller

Rails4の場合

params.require(:project).permit(:name, tasks_attributes: [:id, :name, :_destroy])
model

project

has_many :tasks

task

belongs_to :project

Viewにインデックスを表示する

view
<%= nested_form_for @project do |f|%>
    <%= f.fields_for :tasks do |task_form| %>
        <divclass="task_area"><divid="index_area" ><%= task_form.options[:index] %></div>
            <%= task_form.text_field :name %>
            <%= task_form.link_to_remove "Remove Task" %>
        </div>
        <% task_form.options[:index] %>
    <% end %>
    <p><%= f.link_to_add "Add Task", :tasks %></p>
<% end %>

link_to_add時にインデックスを+1

js
$(document).on('nested:fieldAdded', function(event){
    var current_order = $(this).find('.task_area').length;
    event.field.find('.task_area').val(current_order);
})