La primera vez que me presentaron Ruby on Rails me quedé alucinado. Fue el primer framework de programación que aprendí y tengo que decir que me enamoré un poco. Acababa de aprender a crear aplicaciones con Sinatra y pensaba que era una herramienta bastante impresionante, pero entonces vi lo que Rails podía hacer…

Una de las principales características de Rails que realmente disfruté usando fue el From Helpers. Me permitía evitar escribir todo el HTML para construir un formulario, y a su vez me daba la posibilidad de hacer funciones más complejas. En este artículo voy a desglosar los diferentes ayudantes de formularios que ofrece Rails e incluso tocaré uno nuevo que se lanzó en la versión Rails 5.1.

Crear formularios con HTML puede ser una molestia a veces, especialmente cuando son extra largos con demasiados campos de entrada. Pueden ser aún más complicados cuando necesitas que el formulario envíe datos a un punto final api específico o que esté asociado a un modelo de base de datos. Aquí hay un formulario html para crear un usuario:

<form class="new_user" action="/users" method="post">
<label for="user_name">Name</label>
<input type="text" name="user">
<br>
<label for="user_password">Password</label>
<input type="password" name="user">
<br>
<input type="submit" name="commit" value="Create User" data-disable-with="Create User">
</form>

Como puedes ver, escribir todo esto puede volverse complejo bastante rápido. Si nos fijamos bien en el formulario podemos ver que estamos pasando un atributo de acción y método a nuestro formulario para crear un nuevo usuario. Esto está muy bien pero Rails es muy exigente cuando se trata de enviar formularios. Este formulario en particular no pasaría el corte al ser enviado. Aquí es donde los ayudantes de formularios vienen al rescate.

Ayudantes de formularios

Cuando aprendí a usar los ayudantes de formularios por primera vez, sinceramente no podía creer lo que hacían. Como viste en el formulario anterior que hicimos, se necesita algo de tiempo y complejidad para lograrlo. Sin embargo, con los helpers de formularios esto se puede conseguir con mucho menos trabajo y con bastante «magia».

Hay tres helpers diferentes que nos ayudan a construir formularios rápidos y útiles en Rails, form_tag, form_for, y form_with. El último, form_with, se introdujo en la versión de Rails 5.1 y esencialmente combina los dos ayudantes anteriores.

form_tag

El form_tag es el más básico de los ayudantes y a su vez hace menos «magia» por ti. Seguirá construyendo el formulario por ti, pero tendrás que ser más explícito a la hora de declarar las rutas url y se utiliza principalmente cuando el formulario no está unido a un Controller#action. Usemos un formulario de búsqueda básico como ejemplo:

<%= form_tag("/search", method: "get") do %>
<%= label_tag(:q, "Search for:") %>
<%= text_field_tag(:q) %>
<%= submit_tag("Search") %>
<% end %>

Esto generará el siguiente HTML:

<form accept-charset="UTF-8" action="/search" method="get">
<input name="utf8" type="hidden" value="&#x2713;" />
<label for="q">Search for:</label>
<input name="q" type="text" />
<input name="commit" type="submit" value="Search" />
</form>

Como puedes ver, estamos declarando la ruta que queremos que pasen los parámetros del formulario en el form_tag. Puedes ver que esto tiene lugar en la línea <%= form_tag("/search", method: "get") do %> y también puedes ver que especificamos la petición http. Esto sigue siendo bastante impresionante y podemos ver que Rails se encarga de muchas cosas por nosotros incluso en el helper de formulario básico, pero Rails tiene una versión más potente de esto…

form_for

Form_for es el verdadero negocio. Este helper nos permite vincular un formulario a un objeto, permitiéndonos crear/editar un objeto. Como vimos en el ejemplo de form_tag, teníamos que ser explícitos en la ruta url a utilizar para enviar los parámetros del formulario, pero form_for nos permite abstraer esto. Aquí hay un ejemplo:

<%= form_for @user do |f| %> <%= f.label :name %>
<%= f.text_field :name %>
<%= f.label :password %>
<%= f.password_field :password %>
<%= f.submit %><% end %>

Esto producirá el mismo código que vimos en nuestro primer ejemplo de un formulario html.

<form class="new_user" action="/users" accept-charset="UTF-8" method="post">
<input name="utf8" type="hidden" value="✓">
<input type="hidden" name="authenticity_token"
value="QPJXa5iS/XNvodHhpcwV5q42RoGFWsmZkwL3ATHFfeKqxZ8IQsLs1QjJvcrdO3BwCaOfQ4TxNLDD0b6VbxiACg=="> <label for="user_name">Name</label>
<input type="text" name="user">
<br>
<label for="user_password">Password</label>
<input type="password" name="user">
<br>
<input type="submit" name="commit" value="Create User" data-disable-with="Create User"></form>

Puedes ver inmediatamente lo mucho más limpio que se ve este código usando form_for. ¡Honestamente es un poco alucinante que un código tan pequeño pueda crear todo ese html pero realmente lo hace! Puedes ver en la primera línea de form_for que estamos pasando una variable de instancia del usuario que adjuntará este formulario a ese objeto. Lo otro que mola de pasar esta variable es que Rails buscará la ruta url adecuada por su cuenta, en comparación con el form_tag en el que teníamos que decirle explícitamente dónde enviar los datos.

form_with

  • Tal vez hablar de form_with y de su uso
  • Usar fragmentos de código para el ejemplo

Si miramos las notas de la versión 5.1 de Ruby on Rails, hay una nota que dice que form_for y form_tag se están unificando en form_with. La mayor ventaja de este nuevo helper es que form_withpuede generar etiquetas de formulario basadas en URLs, ámbitos o modelos

¡Vamos a comprobarlo!

form_con usando URLs

Utilicemos el mismo ejemplo que usamos en form_for y apliquémoslo con form_withusando sólo una URL:

<%= form_with url: user_path do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.submit %>
<% end %>

Como puedes ver es muy similar al form_tag en el que especificamos una URL concreta (user_path)

form_with using models

Lo realmente genial de form_with es que también se puede utilizar para pasar objetos del modelo, de forma similar a form_for.

<%= form_with model: @user do |f| %>
<%= f.label :first_name %>
<%= f.text_field :first_name %>
<%= f.label :last_name %>
<%= f.text_field :last_name %>
<%= f.submit %>
<% end %>

Esto creará el mismo HTML que se produjo al usar form_for.

Nuestro mayor beneficio de form_with es que ya no tenemos que preocuparnos de decidir entre form_tag y form_for. Tenemos un ingenioso ayudante que nos permite hacer cualquiera de los dos trabajos con sólo un interruptor en la primera línea del formulario declarado.

Conclusión

Los ayudantes de formularios de Rails son impresionantes y la nueva adición de form_with realmente reúne todos los beneficios tanto de form_tag como de form_for. Ahora tienes una herramienta que te permitirá construir un formulario basado en lo que necesites. Tanto si se trata de un formulario de búsqueda como de un formulario para persistir los datos en tu base de datos, puedes encargarte de ello con los ayudantes de formularios de Rails.

También te sugiero que consultes las guías de Rails para aprender a crear formularios más complejos. Tienes bastantes opciones, desde permitir que un modelo acepte atributos anidados, tener atributos anidados y otros ayudantes de formularios para crear campos de entrada personalizados. Hay muchas cosas con las que jugar cuando se revisan estos documentos, así que aprovecha.

Deja una respuesta

Tu dirección de correo electrónico no será publicada.