partials son lo que Rails usa para remover la duplicidad en las vistas. Aquí hay
un ejemplo:
# app/views/user/show.html.erb
<h1><%= @user.name %></h1>
<%= render 'user_details' %>
# app/views/user/_user_details.html.erb
<%= @user.location %>
<%= @user.about_me %>
La plantilla users/show automáticamente incluirá el contenido de la plantilla
users/_user_details. Nota que los parciales tienen como prefijo un subrayado,
de manera de no confundirlas con vistas regulares. Sin embargo, no incluyas
el subrayado cuando las incluyas dentro del método helper.
CONSEJO: Puedes leer más acerca de parciales en la guía Layouts and Rendering in Rails.
Nuestra acción edit parece muy similar a la acción new, en efecto ellos
comparten el mismo código para mostrar el formulario. Vamos a limpiarlo
usando un parcial.
Crea un nuevo archivo app/views/posts/_form.html.erb con el siguiente contenido:
<%= form_for @post do |f| %>
<% if @post.errors.any? %>
<div id="errorExplanation">
<h2><%= pluralize(@post.errors.count, "error") %> prohibited
this post from being saved:</h2>
<ul>
<% @post.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<p>
<%= f.label :title %><br>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :text %><br>
<%= f.text_area :text %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Todo, excepto la declaración form_for permanece igual. Como form_for
puede averiguar la action y los atributos del method correcto
cuando construye el formulario será explicado en unos momentos.
Por ahora, vamos a actualizar la vista
app/views/posts/new.html.erb para usar el nuevo parcial, reescribiendo completamente:
<h1>New post</h1>
<%= render 'form' %>
<%= link_to 'Back', :action => :index %>
Luego hacer lo mismo a la vista app/views/posts/edit.html.erb:
<h1>Edit post</h1>
<%= render 'form' %>
<%= link_to 'Back', :action => :index %>
Ve con tu navegador a http://localhost:3000/posts/new y trata de crear un nuevo artículo. Todo funciona todavía, ahora tratemos de editar el artículo y recibiremos el siguiente mensaje de error:

Para entender este error necesitamos conocer cómo funciona form_for.
Cuando pasas un objeto a form_for y no especificas la opción de :url,
Rails trata de adivinar las opciones de action y method verificando
si el objeto pasado es un nuevo registro o no. Rails sigue la convención
REST, de esta manera si se está creando un nuevo objeto Post buscará por una
ruta llamada post_path y para actualizar un objeto Post buscará por una
ruta llamada post_path y le pasará el objeto actual. Similarmente, Rails conoce
que debe crear nuevos objetos a través de POST y actualizarlos a través de PUT.
Si ejecutas rake routes desde la consola verás que ya tenemos una ruta
posts_path, la cual fue creada automáticamente por Rails cuando se definió la ruta
por la acción index. Sin embargo, no tenemos aún un post_path, la cual es la
razón por la que recibimos el error anterior.
# rake routes
posts GET /posts(.:format) posts#index
posts_new GET /posts/new(.:format) posts#new
POST /posts(.:format) posts#create
GET /posts/:id(.:format) posts#show
GET /posts/:id/edit(.:format) posts#edit
PUT /posts/:id(.:format) posts#update
root / welcome#index
Para arreglar eso, abrimos el archivo config/routes.rb y modificamos la línea get "posts/:id"
a esto:
get "posts/:id" => "posts#show", :as => :post
La opción :as le dice al método get que queremos hacer que los asistentes
de ruteo llamados post_url y post_path estén disponibles para nuestra aplicación.
Estos son los métodos que form_for necesita cuando estamos editando un artículo y que ahora
están disponibles para actualizar los artículos.
NOTA: La opción :as esta disponible también en los métodos de ruteo
post, put, delete y match.