Patch para Nested Forms no Rails

Posted by Daniel Lopes on 26/01/2009

Michael Koziarski acabou de anunciar no blog oficial do Rails sobre um patch já muito pedido por vários usuários do Rails.

A idéia é que com este patch seja simplificado o trabalho quando precisamos de formulários aninhados… ou seja, um formulário para dois models ou models relacionados.

No exemplo postado por Michael, ele mostra o que atualmente precisamos fazer (veja abaixo):

<% form_for @project do |project_form| %>
  <div>
    <%= project_form.label :name, 'Project name:' %>
    <%= project_form.text_field :name %>
  </div>

  <% @project.tasks.each do |task| %>

    <% new_or_existing = task.new_record? ? 'new' : 'existing' %> 
    <% prefix = "project[#{new_or_existing}_task_attributes][]" %> 
    <% fields_for prefix, task do |task_form| %>
      <p>
        <div>
          <%= task_form.label :name, 'Task:' %>
          <%= task_form.text_field :name %>
        </div>

        <% unless task.new_record? %>
          <div>
            <%= task_form.label :_delete, 'Remove:' %>
            <%= task_form.check_box :_delete %>
          </div>

        <% end %>
      </p>
    <% end %>
  <% end %>

  <%= project_form.submit %>
<% end %>

Que é um formulário para os models na seguinte situação:

class Project < ActiveRecord::Base
  has_many :tasks

  validates_presence_of :name
end


class Task < ActiveRecord::Base
  belongs_to :project

  validates_presence_of :name
end

E como seria esta mesma funcionalidade mas agora com o patch:

<% form_for @project do |project_form| %>
  <div>
    <%= project_form.label :name, 'Project name:' %>
    <%= project_form.text_field :name %>
  </div>

  <!-- Here we call fields_for on the project_form builder instance.
       The block is called for each member of the tasks collection. -->

  <% project_form.fields_for :tasks do |task_form| %>
      <p>
        <div>
          <%= task_form.label :name, 'Task:' %>
          <%= task_form.text_field :name %>
        </div>

        <% unless task_form.object.new_record? %>
          <div>
            <%= task_form.label :_delete, 'Remove:' %>
            <%= task_form.check_box :_delete %>
          </div>
        <% end %>

      </p>
    <% end %>
  <% end %>

  <%= project_form.submit %>
<% end %>

e também uma pequena alteração no model:

class Project < ActiveRecord::Base
  has_many :tasks

  accept_nested_attributes_for :tasks, :allow_destroy => true
end

A idéia do post é que o máximo de pessoas testem esse novo patch, comentem, critiquem e sugiram novas funcionalidades.

Para mais sobre o patch acesse o post oficial aqui

blog comments powered by Disqus