Esta guía no está destinada a ser una lista completa de todos los ayudantes de formulario disponibles. Por favor, consulta la documentación de la API de Rails para una lista exhaustiva de ayudantes de formulario y sus argumentos.
1 Trabajando con Formularios Básicos
El principal ayudante de formulario es form_with
.
<%= form_with do |form| %>
Contenido del formulario
<% end %>
Cuando se llama sin argumentos, crea una etiqueta HTML <form>
con el valor del atributo method
establecido en post
y el valor del atributo action
establecido en la página actual. Por ejemplo, suponiendo que la página actual es una página de inicio en /home
, el HTML generado se verá así:
<form action="/home" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="Lz6ILqUEs2CGdDa-oz38TqcqQORavGnbGkG0CQA8zc8peOps-K7sHgFSTPSkBx89pQxh3p5zPIkjoOTiA_UWbQ" autocomplete="off">
Contenido del formulario
</form>
Observa que el formulario contiene un elemento input
con tipo hidden
. Este input oculto authenticity_token
es requerido para envíos de formularios no GET. Este token es una función de seguridad en Rails utilizada para prevenir ataques de falsificación de solicitudes entre sitios (CSRF), y los ayudantes de formulario lo generan automáticamente para cada formulario no GET (suponiendo que la función de seguridad esté habilitada). Puedes leer más sobre esto en la guía Asegurando Aplicaciones Rails.
1.1 Un Formulario de Búsqueda Genérico
Uno de los formularios más básicos en la web es un formulario de búsqueda. Este formulario contiene:
- un elemento de formulario con método "GET",
- una etiqueta para la entrada,
- un elemento de entrada de texto, y
- un elemento de envío.
Aquí se muestra cómo crear un formulario de búsqueda con form_with
:
<%= form_with url: "/search", method: :get do |form| %>
<%= form.label :query, "Buscar:" %>
<%= form.text_field :query %>
<%= form.submit "Buscar" %>
<% end %>
Esto generará el siguiente HTML:
<form action="/search" accept-charset="UTF-8" method="get">
<label for="query">Buscar:</label>
<input type="text" name="query" id="query">
<input type="submit" name="commit" value="Buscar" data-disable-with="Buscar">
</form>
Observa que para el formulario de búsqueda estamos usando la opción url
de form_with
. Establecer url: "/search"
cambia el valor de acción del formulario del valor por defecto de la ruta de la página actual a action="/search"
.
En general, pasar url: my_path
a form_with
le dice al formulario dónde hacer la solicitud. La otra opción es pasar objetos de modelo Active Model al formulario, como aprenderás a continuación. También puedes usar ayudantes de URL.
El ejemplo de formulario de búsqueda anterior también muestra el objeto form builder. Aprenderás sobre los muchos ayudantes proporcionados por el objeto form builder (como form.label
y form.text_field
) en la siguiente sección.
CONSEJO: Para cada elemento de input
de formulario, se genera un atributo id
a partir de su nombre ("query"
en el ejemplo anterior). Estos IDs pueden ser muy útiles para el estilo CSS o la manipulación de controles de formulario con JavaScript.
IMPORTANTE: Usa "GET" como el método para formularios de búsqueda. En general, las convenciones de Rails fomentan el uso del verbo HTTP correcto para las acciones del controlador. Usar "GET" para la búsqueda permite a los usuarios marcar una búsqueda específica.
1.2 Ayudantes para Generar Elementos de Formulario
El objeto form builder producido por form_with
proporciona muchos métodos de ayuda para generar elementos de formulario comunes como campos de texto, casillas de verificación y botones de opción.
El primer argumento de estos métodos es siempre el nombre de la entrada. Esto es útil recordar porque cuando se envía el formulario, ese nombre se pasará al controlador junto con los datos del formulario en el hash params
. El nombre será la clave en los params
para el valor ingresado por el usuario para ese campo.
Por ejemplo, si el formulario contiene <%= form.text_field :query %>
, entonces podrías obtener el valor de este campo en el controlador con params[:query]
.
Al nombrar las entradas, Rails utiliza ciertas convenciones que hacen posible enviar parámetros con valores no escalares como matrices o hashes, que también serán accesibles en params
. Puedes leer más sobre ellos en la sección Convenciones de Nombres de Entrada de Formularios y Hash de Params de esta guía. Para obtener detalles sobre el uso preciso de estos ayudantes, consulta la documentación de la API.
1.2.1 Casillas de Verificación
Una casilla de verificación es un control de formulario que permite seleccionar o deseleccionar un único valor. Un grupo de casillas de verificación generalmente se utiliza para permitir que un usuario elija una o más opciones del grupo.
Aquí hay un ejemplo con tres casillas de verificación en un formulario:
<%= form.check_box :biography %>
<%= form.label :biography, "Biografía" %>
<%= form.check_box :romance %>
<%= form.label :romance, "Romance" %>
<%= form.check_box :mystery %>
<%= form.label :mystery, "Misterio" %>
Lo anterior generará lo siguiente:
<input name="biography" type="hidden" value="0" autocomplete="off"><input type="checkbox" value="1" name="biography" id="biography">
<label for="biography">Biografía</label>
<input name="romance" type="hidden" value="0" autocomplete="off"><input type="checkbox" value="1" name="romance" id="romance">
<label for="romance">Romance</label>
<input name="mystery" type="hidden" value="0" autocomplete="off"><input type="checkbox" value="1" name="mystery" id="mystery">
<label for="mystery">Misterio</label>
El primer parámetro de check_box
es el nombre de la entrada que se puede encontrar en el hash params
. Si el usuario ha marcado solo la casilla de verificación "Biografía", el hash params
contendría:
{
"biography" => "1",
"romance" => "0",
"mystery" => "0"
}
Puedes usar params[:biography]
para verificar si esa casilla de verificación está seleccionada por el usuario.
Los valores de la casilla de verificación (los valores que aparecerán en params
) pueden especificarse opcionalmente usando los parámetros checked_value
y unchecked_value
. Consulta la documentación de la API para más detalles.
También hay un collection_check_boxes
, del cual puedes aprender en la sección de Ayudantes Relacionados con Colecciones.
1.2.2 Botones de Opción
Los botones de opción son controles de formulario que solo permiten al usuario seleccionar una opción a la vez de la lista de opciones.
Por ejemplo, botones de opción para elegir tu sabor de helado favorito:
<%= form.radio_button :flavor, "chocolate_chip" %>
<%= form.label :flavor_chocolate_chip, "Chocolate Chip" %>
<%= form.radio_button :flavor, "vanilla" %>
<%= form.label :flavor_vanilla, "Vainilla" %>
<%= form.radio_button :flavor, "hazelnut" %>
<%= form.label :flavor_hazelnut, "Avellana" %>
Lo anterior generará el siguiente HTML:
<input type="radio" value="chocolate_chip" name="flavor" id="flavor_chocolate_chip">
<label for="flavor_chocolate_chip">Chocolate Chip</label>
<input type="radio" value="vanilla" name="flavor" id="flavor_vanilla">
<label for="flavor_vanilla">Vainilla</label>
<input type="radio" value="hazelnut" name="flavor" id="flavor_hazelnut">
<label for="flavor_hazelnut">Avellana</label>
El segundo argumento de radio_button
es el valor de la entrada. Debido a que estos botones de opción comparten el mismo nombre (flavor
), el usuario solo podrá seleccionar uno de ellos, y params[:flavor]
contendrá "chocolate_chip"
, "vanilla"
, o hazelnut
.
NOTA: Usa siempre etiquetas para casillas de verificación y botones de opción. Asocian texto con una opción específica usando el atributo for
y, al expandir la región clickeable, facilitan a los usuarios hacer clic en las entradas.
1.3 Otros Ayudantes de Interés
Hay muchos otros controles de formulario incluyendo texto, correo electrónico, contraseña, fecha y hora. Los ejemplos a continuación muestran algunos más ayudantes y su HTML generado.
Ayudantes relacionados con fechas y horas:
<%= form.date_field :born_on %>
<%= form.time_field :started_at %>
<%= form.datetime_local_field :graduation_day %>
<%= form.month_field :birthday_month %>
<%= form.week_field :birthday_week %>
Salida:
<input type="date" name="born_on" id="born_on">
<input type="time" name="started_at" id="started_at">
<input type="datetime-local" name="graduation_day" id="graduation_day">
<input type="month" name="birthday_month" id="birthday_month">
<input type="week" name="birthday_week" id="birthday_week">
Ayudantes con formato especial:
<%= form.password_field :password %>
<%= form.email_field :address %>
<%= form.telephone_field :phone %>
<%= form.url_field :homepage %>
Salida:
<input type="password" name="password" id="password">
<input type="email" name="address" id="address">
<input type="tel" name="phone" id="phone">
<input type="url" name="homepage" id="homepage">
Otros ayudantes comunes:
<%= form.text_area :message, size: "70x5" %>
<%= form.hidden_field :parent_id, value: "foo" %>
<%= form.number_field :price, in: 1.0..20.0, step: 0.5 %>
<%= form.range_field :discount, in: 1..100 %>
<%= form.search_field :name %>
<%= form.color_field :favorite_color %>
Salida:
<textarea name="message" id="message" cols="70" rows="5"></textarea>
<input value="foo" autocomplete="off" type="hidden" name="parent_id" id="parent_id">
<input step="0.5" min="1.0" max="20.0" type="number" name="price" id="price">
<input min="1" max="100" type="range" name="discount" id="discount">
<input type="search" name="name" id="name">
<input value="#000000" type="color" name="favorite_color" id="favorite_color">
Los inputs ocultos no se muestran al usuario pero en su lugar contienen datos como cualquier entrada textual. Los valores dentro de ellos pueden cambiarse con JavaScript.
CONSEJO: Si estás usando campos de entrada de contraseña, es posible que desees configurar tu aplicación para evitar que esos parámetros se registren. Puedes aprender cómo en la guía Asegurando Aplicaciones Rails.
2 Creando Formularios con Objetos de Modelo
2.1 Vinculando un Formulario a un Objeto
El ayudante form_with
tiene una opción :model
que te permite vincular el objeto form builder a un objeto de modelo. Esto significa que el formulario estará limitado a ese objeto de modelo, y los campos del formulario se poblarán con valores de ese objeto de modelo.
Por ejemplo, si tenemos un objeto de modelo @book
:
@book = Book.find(42)
# => #<Book id: 42, title: "Walden", author: "Henry David Thoreau">
Y el siguiente formulario para crear un nuevo libro:
<%= form_with model: @book do |form| %>
<div>
<%= form.label :title %>
<%= form.text_field :title %>
</div>
<div>
<%= form.label :author %>
<%= form.text_field :author %>
</div>
<%= form.submit %>
<% end %>
Generará este HTML:
<form action="/books" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="ChwHeyegcpAFDdBvXvDuvbfW7yCA3e8gvhyieai7DhG28C3akh-dyuv-IBittsjPrIjETlQQvQJ91T77QQ8xWA" autocomplete="off">
<div>
<label for="book_title">Título</label>
<input type="text" name="book[title]" id="book_title">
</div>
<div>
<label for="book_author">Autor</label>
<input type="text" name="book[author]" id="book_author">
</div>
<input type="submit" name="commit" value="Crear Libro" data-disable-with="Crear Libro">
</form>
Algunas cosas importantes a notar al usar form_with
con un objeto de modelo:
- La
action
del formulario se llena automáticamente con un valor apropiado,action="/books"
. Si estuvieras actualizando un libro, seríaaction="/books/42"
. - Los nombres de los campos del formulario están limitados con
book[...]
. Esto significa queparams[:book]
será un hash que contiene los valores de todos estos campos. Puedes leer más sobre la importancia de los nombres de entrada en el capítulo Convenciones de Nombres de Entrada de Formularios y Hash de Params de esta guía. - El botón de envío se le da automáticamente un valor de texto apropiado, "Crear Libro" en este caso.
CONSEJO: Típicamente tus entradas de formulario reflejarán atributos del modelo. Sin embargo, no tienen que hacerlo. Si hay otra información que necesitas, puedes incluir un campo en tu formulario y acceder a él a través de params[:book][:my_non_attribute_input]
.
2.1.1 Formularios de Clave Primaria Compuesta
Si tienes un modelo con una clave primaria compuesta, la sintaxis de construcción de formularios es la misma con una salida ligeramente diferente.
Por ejemplo, para actualizar un objeto de modelo @book
con una clave compuesta [:author_id, :id]
como esta:
@book = Book.find([2, 25])
# => #<Book id: 25, title: "Some book", author_id: 2>
El siguiente formulario:
<%= form_with model: @book do |form| %>
<%= form.text_field :title %>
<%= form.submit %>
<% end %>
Generará esta salida HTML:
<form action="/books/2_25" method="post" accept-charset="UTF-8" >
<input name="authenticity_token" type="hidden" value="ChwHeyegcpAFDdBvXvDuvbfW7yCA3e8gvhyieai7DhG28C3akh-dyuv-IBittsjPrIjETlQQvQJ91T77QQ8xWA" />
<input type="text" name="book[title]" id="book_title" value="Some book" />
<input type="submit" name="commit" value="Actualizar Libro" data-disable-with="Actualizar Libro">
</form>
Observa que la URL generada contiene el author_id
y id
delimitados por un guion bajo. Una vez enviado, el controlador puede extraer cada valor de clave primaria de los parámetros y actualizar el registro como lo haría con una clave primaria singular.
2.1.2 El Ayudante fields_for
El ayudante fields_for
se utiliza para renderizar campos para objetos de modelo relacionados dentro del mismo formulario. El modelo "interno" asociado generalmente está relacionado con el modelo "principal" del formulario a través de una asociación de Active Record. Por ejemplo, si tuvieras un modelo Person
con un modelo asociado ContactDetail
, podrías crear un único formulario con entradas para ambos modelos de esta manera:
<%= form_with model: @person do |person_form| %>
<%= person_form.text_field :name %>
<%= fields_for :contact_detail, @person.contact_detail do |contact_detail_form| %>
<%= contact_detail_form.text_field :phone_number %>
<% end %>
<% end %>
Lo anterior producirá la siguiente salida:
<form action="/people" accept-charset="UTF-8" method="post">
<input type="hidden" name="authenticity_token" value="..." autocomplete="off" />
<input type="text" name="person[name]" id="person_name" />
<input type="text" name="contact_detail[phone_number]" id="contact_detail_phone_number" />
</form>
El objeto producido por fields_for
es un form builder como el que produce form_with
. El ayudante fields_for
crea un enlace similar pero sin renderizar una etiqueta <form>
. Puedes aprender más sobre fields_for
en los documentos de la API.
2.2 Confiando en la Identificación de Registros
Al tratar con recursos RESTful, las llamadas a form_with
pueden simplificarse confiando en la identificación de registros. Esto significa que pasas la instancia del modelo y dejas que Rails determine el nombre del modelo, el método y otras cosas. En el ejemplo a continuación para crear un nuevo registro, ambas llamadas a form_with
generan el mismo HTML:
# forma más larga:
form_with(model: @article, url: articles_path)
# forma abreviada:
form_with(model: @article)
De manera similar, para editar un artículo existente como a continuación, ambas llamadas a form_with
también generarán el mismo HTML:
# forma más larga:
form_with(model: @article, url: article_path(@article), method: "patch")
# forma abreviada:
form_with(model: @article)
Observa cómo la invocación abreviada de form_with
es convenientemente la misma, independientemente de si el registro es nuevo o existente. La identificación de registros es lo suficientemente inteligente como para determinar si el registro es nuevo preguntando a record.persisted?
. También selecciona el camino correcto para enviar, y el nombre basado en la clase del objeto.
Esto asume que el modelo Article
está declarado con resources :articles
en el archivo de rutas.
Si tienes un recurso singular, necesitarás llamar a resource
y resolve
para que funcione con form_with
:
resource :article
resolve('Article') { [:article] }
CONSEJO: Declarar un recurso tiene una serie de efectos secundarios. Consulta la guía Rutas de Rails desde el Exterior Hacia Adentro para obtener más información sobre cómo configurar y usar recursos.
ADVERTENCIA: Cuando estás usando herencia de tabla única con tus modelos, no puedes confiar en la identificación de registros en una subclase si solo su clase padre está declarada como recurso. Tendrás que especificar :url
, y :scope
(el nombre del modelo) explícitamente.
2.3 Trabajando con Espacios de Nombres
Si tienes rutas con espacios de nombres, form_with
tiene una abreviatura para eso. Por ejemplo, si tu aplicación tiene un espacio de nombres admin
:
form_with model: [:admin, @article]
Lo anterior creará un formulario que se envía al Admin::ArticlesController
dentro del espacio de nombres admin, por lo tanto enviando a admin_article_path(@article)
en el caso de una actualización.
Si tienes varios niveles de espacios de nombres, la sintaxis es similar:
form_with model: [:admin, :management, @article]
Para más información sobre el sistema de enrutamiento de Rails y las convenciones asociadas, consulta la guía Rutas de Rails desde el Exterior Hacia Adentro.
2.4 Formularios con Métodos PATCH, PUT, o DELETE
El marco de Rails fomenta el diseño RESTful, lo que significa que los formularios en tu aplicación harán solicitudes donde el method
es PATCH
, PUT
, o DELETE
además de GET
y POST
. Sin embargo, los formularios HTML no soportan métodos distintos de GET
y POST
cuando se trata de enviar formularios.
Rails resuelve esta limitación emulando otros métodos sobre POST con un input oculto llamado "_method"
. Por ejemplo:
form_with(url: search_path, method: "patch")
El formulario anterior generará esta salida HTML:
<form action="/search" accept-charset="UTF-8" method="post">
<input type="hidden" name="_method" value="patch" autocomplete="off">
<input type="hidden" name="authenticity_token" value="R4quRuXQAq75TyWpSf8AwRyLt-R1uMtPP1dHTTWJE5zbukiaY8poSTXxq3Z7uAjXfPHiKQDsWE1i2_-h0HSktQ" autocomplete="off">
<!-- ... -->
</form>
Al analizar los datos enviados por POST, Rails tomará en cuenta el parámetro especial _method
y procederá como si el método HTTP de la solicitud fuera el establecido como el valor de _method
(PATCH
en este ejemplo).
Al renderizar un formulario, los botones de envío pueden anular el atributo method
declarado a través de la palabra clave formmethod:
:
<%= form_with url: "/posts/1", method: :patch do |form| %>
<%= form.button "Eliminar", formmethod: :delete, data: { confirm: "¿Estás seguro?" } %>
<%= form.button "Actualizar" %>
<% end %>
Similar a los elementos <form>
, la mayoría de los navegadores no soportan anular métodos de formulario declarados a través de formmethod distintos de GET
y POST
.
Rails resuelve este problema emulando otros métodos sobre POST a través de una combinación de formmethod, value, y name:
<form accept-charset="UTF-8" action="/posts/1" method="post">
<input name="_method" type="hidden" value="patch" />
<input name="authenticity_token" type="hidden" value="f755bb0ed134b76c432144748a6d4b7a7ddf2b71" />
<!-- ... -->
<button type="submit" formmethod="post" name="_method" value="delete" data-confirm="¿Estás seguro?">Eliminar</button>
<button type="submit" name="button">Actualizar</button>
</form>
En este caso, el botón "Actualizar" será tratado como PATCH
y el botón "Eliminar" será tratado como DELETE
.
3 Creando Cuadros de Selección con Facilidad
Los cuadros de selección, también conocidos como listas desplegables, permiten a los usuarios seleccionar de una lista de opciones. El HTML para los cuadros de selección requiere una cantidad decente de marcado: un elemento <option>
para cada opción a elegir. Rails proporciona métodos de ayuda para ayudar a generar ese marcado.
Por ejemplo, digamos que tenemos una lista de ciudades para que el usuario elija. Podemos usar el ayudante select
:
<%= form.select :city, ["Berlin", "Chicago", "Madrid"] %>
Lo anterior generará esta salida HTML:
<select name="city" id="city">
<option value="Berlin">Berlín</option>
<option value="Chicago">Chicago</option>
<option value="Madrid">Madrid</option>
</select>
Y la selección estará disponible en params[:city]
como de costumbre.
También podemos especificar valores <option>
que difieren de sus etiquetas:
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]] %>
Salida:
<select name="city" id="city">
<option value="BE">Berlín</option>
<option value="CHI">Chicago</option>
<option value="MD">Madrid</option>
</select>
De esta manera, el usuario verá el nombre completo de la ciudad, pero params[:city]
será uno de "BE"
, "CHI"
, o "MD"
.
Por último, podemos especificar una opción predeterminada para el cuadro de selección con el argumento :selected
:
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]], selected: "CHI" %>
Salida:
<select name="city" id="city">
<option value="BE">Berlín</option>
<option value="CHI" selected="selected">Chicago</option>
<option value="MD">Madrid</option>
</select>
3.1 Grupos de Opciones para Cuadros de Selección
En algunos casos, podemos querer mejorar la experiencia del usuario agrupando opciones relacionadas. Podemos hacerlo pasando un Hash
(o un Array
comparable) a select
:
<%= form.select :city,
{
"Europa" => [ ["Berlin", "BE"], ["Madrid", "MD"] ],
"América del Norte" => [ ["Chicago", "CHI"] ],
},
selected: "CHI" %>
Salida:
<select name="city" id="city">
<optgroup label="Europa">
<option value="BE">Berlín</option>
<option value="MD">Madrid</option>
</optgroup>
<optgroup label="América del Norte">
<option value="CHI" selected="selected">Chicago</option>
</optgroup>
</select>
3.2 Vinculando Cuadros de Selección a Objetos de Modelo
Al igual que otros controles de formulario, un cuadro de selección puede estar vinculado a un atributo de modelo. Por ejemplo, si tenemos un objeto de modelo @person
como:
@person = Person.new(city: "MD")
El siguiente formulario:
<%= form_with model: @person do |form| %>
<%= form.select :city, [["Berlin", "BE"], ["Chicago", "CHI"], ["Madrid", "MD"]] %>
<% end %>
Generará este cuadro de selección:
<select name="person[city]" id="person_city">
<option value="BE">Berlín</option>
<option value="CHI">Chicago</option>
<option value="MD" selected="selected">Madrid</option>
</select>
La única diferencia es que la opción seleccionada se encontrará en params[:person][:city]
en lugar de params[:city]
.
Observa que la opción apropiada fue automáticamente marcada como selected="selected"
. Dado que este cuadro de selección estaba vinculado a un registro @person
existente, no necesitábamos especificar un argumento :selected
.
4 Usando Ayudantes de Formulario de Fecha y Hora
Además de los ayudantes date_field
y time_field
mencionados anteriormente, Rails proporciona ayudantes alternativos de fecha y hora que renderizan cuadros de selección simples. El ayudante date_select
renderiza un cuadro de selección separado para año, mes y día.
Por ejemplo, si tenemos un objeto de modelo @person
como:
@person = Person.new(birth_date: Date.new(1995, 12, 21))
El siguiente formulario:
<%= form_with model: @person do |form| %>
<%= form.date_select :birth_date %>
<% end %>
Generará cuadros de selección como:
<select name="person[birth_date(1i)]" id="person_birth_date_1i">
<option value="1990">1990</option>
<option value="1991">1991</option>
<option value="1992">1992</option>
<option value="1993">1993</option>
<option value="1994">1994</option>
<option value="1995" selected="selected">1995</option>
<option value="1996">1996</option>
<option value="1997">1997</option>
<option value="1998">1998</option>
<option value="1999">1999</option>
<option value="2000">2000</option>
</select>
<select name="person[birth_date(2i)]" id="person_birth_date_2i">
<option value="1">Enero</option>
<option value="2">Febrero</option>
<option value="3">Marzo</option>
<option value="4">Abril</option>
<option value="5">Mayo</option>
<option value="6">Junio</option>
<option value="7">Julio</option>
<option value="8">Agosto</option>
<option value="9">Septiembre</option>
<option value="10">Octubre</option>
<option value="11">Noviembre</option>
<option value="12" selected="selected">Diciembre</option>
</select>
<select name="person[birth_date(3i)]" id="person_birth_date_3i">
<option value="1">1</option>
...
<option value="21" selected="selected">21</option>
...
<option value="31">31</option>
</select>
Observa que, cuando se envía el formulario, no habrá un solo valor en el hash params
que contenga la fecha completa. En su lugar, habrá varios valores con nombres especiales como "birth_date(1i)"
. Sin embargo, Active Model sabe cómo ensamblar estos valores en una fecha completa, basada en el tipo declarado del atributo del modelo. Así que podemos pasar params[:person]
a Person.new
o Person#update
tal como lo haríamos si el formulario usara un solo campo para representar la fecha completa.
Además del ayudante date_select
, Rails proporciona time_select
que genera cuadros de selección para la hora y el minuto. También hay datetime_select
que combina tanto cuadros de selección de fecha como de hora.
4.1 Cuadros de Selección para Componentes de Fecha o Hora
Rails también proporciona ayudantes para renderizar cuadros de selección para componentes individuales de fecha y hora: select_year
, select_month
, select_day
, select_hour
, select_minute
, y select_second
. Estos ayudantes son métodos "desnudos", lo que significa que no se llaman en una instancia de form builder. Por ejemplo:
<%= select_year 2024, prefix: "party" %>
Lo anterior genera un cuadro de selección como:
<select id="party_year" name="party[year]">
<option value="2019">2019</option>
<option value="2020">2020</option>
<option value="2021">2021</option>
<option value="2022">2022</option>
<option value="2023">2023</option>
<option value="2024" selected="selected">2024</option>
<option value="2025">2025</option>
<option value="2026">2026</option>
<option value="2027">2027</option>
<option value="2028">2028</option>
<option value="2029">2029</option>
</select>
Para cada uno de estos ayudantes, puedes especificar un objeto Date
o Time
en lugar de un número como valor predeterminado (por ejemplo <%= select_year Date.today, prefix: "party" %>
en lugar de lo anterior), y las partes de fecha y hora apropiadas serán extraídas y utilizadas.
4.2 Selección de Zona Horaria
Cuando necesitas preguntar a los usuarios en qué zona horaria están, hay un ayudante muy conveniente time_zone_select
para usar.
Típicamente, tendrías que proporcionar una lista de opciones de zona horaria para que los usuarios seleccionen. Esto puede ser tedioso si no fuera por la lista de objetos predefinidos ActiveSupport::TimeZone
. El ayudante time_with_zone
envuelve esto y puede ser usado de la siguiente manera:
<%= form.time_zone_select :time_zone %>
Salida:
<select name="time_zone" id="time_zone">
<option value="International Date Line West">(GMT-12:00) International Date Line West</option>
<option value="American Samoa">(GMT-11:00) American Samoa</option>
<option value="Midway Island">(GMT-11:00) Midway Island</option>
<option value="Hawaii">(GMT-10:00) Hawaii</option>
<option value="Alaska">(GMT-09:00) Alaska</option>
...
<option value="Samoa">(GMT+13:00) Samoa</option>
<option value="Tokelau Is.">(GMT+13:00) Tokelau Is.</option>
</select>
5 Ayudantes Relacionados con Colecciones
Si necesitas generar un conjunto de opciones a partir de una colección de objetos arbitrarios, Rails tiene collection_select
, collection_radio_button
, y collection_check_boxes
.
Para ver cuándo son útiles estos ayudantes, supongamos que tienes un modelo City
y una asociación belongs_to :city
correspondiente con Person
:
class City < ApplicationRecord
end
class Person < ApplicationRecord
belongs_to :city
end
Suponiendo que tenemos las siguientes ciudades almacenadas en la base de datos:
City.order(:name).map { |city| [city.name, city.id] }
# => [["Berlin", 1], ["Chicago", 3], ["Madrid", 2]]
Podemos permitir que el usuario elija entre las ciudades con el siguiente formulario:
<%= form_with model: @person do |form| %>
<%= form.select :city_id, City.order(:name).map { |city| [city.name, city.id] } %>
<% end %>
Lo anterior generará este HTML:
<select name="person[city_id]" id="person_city_id">
<option value="1">Berlín</option>
<option value="3">Chicago</option>
<option value="2">Madrid</option>
</select>
El ejemplo anterior muestra cómo generarías las opciones manualmente. Sin embargo, Rails tiene ayudantes que generan opciones a partir de una colección sin tener que iterar explícitamente sobre ella. Estos ayudantes determinan el valor y la etiqueta de texto de cada opción llamando a métodos especificados en cada objeto de la colección.
NOTA: Al renderizar un campo para una asociación belongs_to
, debes especificar el nombre de la clave externa (city_id
en el ejemplo anterior), en lugar del nombre de la asociación en sí.
5.1 El Ayudante collection_select
Para generar un cuadro de selección, podemos usar collection_select
:
<%= form.collection_select :city_id, City.order(:name), :id, :name %>
Lo anterior genera el mismo HTML que la iteración manual anterior:
<select name="person[city_id]" id="person_city_id">
<option value="1">Berlín</option>
<option value="3">Chicago</option>
<option value="2">Madrid</option>
</select>
NOTA: El orden de los argumentos para collection_select
es diferente del orden para select
. Con collection_select
especificamos el método de valor primero (:id
en el ejemplo anterior), y el método de etiqueta de texto segundo (:name
en el ejemplo anterior). Esto es opuesto al orden utilizado al especificar opciones para el ayudante select
, donde la etiqueta de texto viene primero y el valor segundo (["Berlín", 1]
en el ejemplo anterior).
5.2 El Ayudante collection_radio_buttons
Para generar un conjunto de botones de opción, podemos usar collection_radio_buttons
:
<%= form.collection_radio_buttons :city_id, City.order(:name), :id, :name %>
Salida:
<input type="radio" value="1" name="person[city_id]" id="person_city_id_1">
<label for="person_city_id_1">Berlín</label>
<input type="radio" value="3" name="person[city_id]" id="person_city_id_3">
<label for="person_city_id_3">Chicago</label>
<input type="radio" value="2" name="person[city_id]" id="person_city_id_2">
<label for="person_city_id_2">Madrid</label>
5.3 El Ayudante collection_check_boxes
Para generar un conjunto de casillas de verificación, por ejemplo, para soportar una asociación has_and_belongs_to_many
, podemos usar collection_check_boxes
:
<%= form.collection_check_boxes :interest_ids, Interest.order(:name), :id, :name %>
Salida:
<input type="checkbox" name="person[interest_id][]" value="3" id="person_interest_id_3">
<label for="person_interest_id_3">Ingeniería</label>
<input type="checkbox" name="person[interest_id][]" value="4" id="person_interest_id_4">
<label for="person_interest_id_4">Matemáticas</label>
<input type="checkbox" name="person[interest_id][]" value="1" id="person_interest_id_1">
<label for="person_interest_id_1">Ciencia</label>
<input type="checkbox" name="person[interest_id][]" value="2" id="person_interest_id_2">
<label for="person_interest_id_2">Tecnología</label>
6 Subiendo Archivos
Una tarea común con los formularios es permitir a los usuarios subir un archivo. Podría ser una imagen de avatar o un archivo CSV con datos para procesar. Los campos de carga de archivos pueden renderizarse con el ayudante file_field
.
<%= form_with model: @person do |form| %>
<%= form.file_field :csv_file %>
<% end %>
Lo más importante a recordar con las cargas de archivos es que el atributo enctype
del formulario renderizado debe establecerse en multipart/form-data
. Esto se hace automáticamente si usas un file_field
dentro de un form_with
. También puedes establecer el atributo manualmente:
<%= form_with url: "/uploads", multipart: true do |form| %>
<%= file_field_tag :csv_file %>
<% end %>
Ambos, generan el siguiente formulario HTML:
<form enctype="multipart/form-data" action="/people" accept-charset="UTF-8" method="post">
<!-- ... -->
</form>
Ten en cuenta que, según las convenciones de form_with
, los nombres de los campos en los dos formularios anteriores serán diferentes. En el primer formulario, será person[csv_file]
(accesible a través de params[:person][:csv_file]
), y en el segundo formulario será solo csv_file
(accesible a través de params[:csv_file]
).
6.1 Ejemplo de Carga de Archivo CSV
Al usar file_field
, el objeto en el hash params
es una instancia de ActionDispatch::Http::UploadedFile
. Aquí hay un ejemplo de cómo guardar datos en un archivo CSV subido a registros en tu aplicación:
require 'csv'
def upload
uploaded_file = params[:csv_file]
if uploaded_file.present?
csv_data = CSV.parse(uploaded_file.read, headers: true)
csv_data.each do |row|
# Procesar cada fila del archivo CSV
# SomeInvoiceModel.create(amount: row['Amount'], status: row['Status'])
Rails.logger.info row.inspect
#<CSV::Row "id":"po_1KE3FRDSYPMwkcNz9SFKuaYd" "Amount":"96.22" "Created (UTC)":"2022-01-04 02:59" "Arrival Date (UTC)":"2022-01-05 00:00" "Status":"paid">
end
end
# ...
end
Si el archivo es una imagen que necesita almacenarse con un modelo (por ejemplo, la foto de perfil de un usuario), hay una serie de tareas a considerar, como dónde almacenar el archivo (en Disco, Amazon S3, etc.), redimensionar archivos de imagen, y generar miniaturas, etc. Active Storage está diseñado para ayudar con estas tareas.
7 Personalizando Constructores de Formularios
Llamamos constructores de formularios a los objetos producidos por form_with
o fields_for
. Los constructores de formularios te permiten generar elementos de formulario asociados con un objeto de modelo y son una instancia de ActionView::Helpers::FormBuilder
. Esta clase puede extenderse para agregar ayudantes personalizados para tu aplicación.
Por ejemplo, si deseas mostrar un text_field
junto con una label
en toda tu aplicación, podrías agregar el siguiente método de ayuda a application_helper.rb
:
module ApplicationHelper
def text_field_with_label(form, attribute)
form.label(attribute) + form.text_field(attribute)
end
end
Y usarlo en un formulario como de costumbre:
<%= form_with model: @person do |form| %>
<%= text_field_with_label form, :first_name %>
<% end %>
Pero también puedes crear una subclase de ActionView::Helpers::FormBuilder
, y agregar los ayudantes allí. Después de definir esta subclase LabellingFormBuilder
:
class LabellingFormBuilder < ActionView::Helpers::FormBuilder
def text_field(attribute, options = {})
# super llamará al método text_field original
label(attribute) + super
end
end
El formulario anterior puede ser reemplazado por:
<%= form_with model: @person, builder: LabellingFormBuilder do |form| %>
<%= form.text_field :first_name %>
<% end %>
Si reutilizas esto con frecuencia, podrías definir un ayudante labeled_form_with
que aplique automáticamente la opción builder: LabellingFormBuilder
:
module ApplicationHelper
def labeled_form_with(**options, &block)
options[:builder] = LabellingFormBuilder
form_with(**options, &block)
end
end
Lo anterior puede ser usado en lugar de form_with
:
<%= labeled_form_with model: @person do |form| %>
<%= form.text_field :first_name %>
<% end %>
Los tres casos anteriores (el ayudante text_field_with_label
, la subclase LabellingFormBuilder
, y el ayudante labeled_form_with
) generarán la misma salida HTML:
<form action="/people" accept-charset="UTF-8" method="post">
<!-- ... -->
<label for="person_first_name">Nombre</label>
<input type="text" name="person[first_name]" id="person_first_name">
</form>
El constructor de formularios utilizado también determina qué sucede cuando haces:
<%= render partial: f %>
Si f
es una instancia de ActionView::Helpers::FormBuilder
, entonces esto renderizará la parcial form
, estableciendo el objeto de la parcial al constructor de formularios. Si el constructor de formularios es de la clase LabellingFormBuilder
, entonces la parcial labelling_form
sería renderizada en su lugar.
Las personalizaciones de los constructores de formularios, como LabellingFormBuilder
, ocultan los detalles de implementación (y pueden parecer excesivas para el simple ejemplo anterior). Elige entre diferentes personalizaciones, extendiendo la clase FormBuilder
o creando ayudantes, según la frecuencia con la que tus formularios usen los elementos personalizados.
8 Convenciones de Nombres de Entrada de Formularios y Hash params
Todos los ayudantes de formularios descritos anteriormente ayudan a generar el HTML para los elementos de formulario para que el usuario pueda ingresar varios tipos de entrada. ¿Cómo accedes a los valores de entrada del usuario en el Controlador? El hash params
es la respuesta. Ya has visto el hash params
en el ejemplo anterior. Esta sección cubrirá más explícitamente las convenciones de nombres sobre cómo se estructura la entrada de formularios en el hash params
.
El hash params
puede contener arrays y arrays de hashes. Los valores pueden estar en el nivel superior del hash params
o anidados en otro hash. Por ejemplo, en una acción estándar create
para un modelo Person, params[:person]
será un hash de todos los atributos para el objeto Person
.
Ten en cuenta que los formularios HTML no tienen una estructura inherente para los datos de entrada del usuario, todo lo que generan son pares de cadenas nombre-valor. Los arrays y hashes que ves en tu aplicación son el resultado de convenciones de nombres de parámetros que Rails utiliza.
NOTA: Los campos en el hash params
deben ser permitidos en el controlador.
8.1 Estructura Básica
Las dos estructuras básicas para los datos de entrada de formularios de usuario son arrays y hashes.
Los hashes reflejan la sintaxis utilizada para acceder al valor en params
. Por ejemplo, si un formulario contiene:
<input id="person_name" name="person[name]" type="text" value="Henry"/>
el hash params
contendrá
{ 'person' => { 'name' => 'Henry' } }
y params[:person][:name]
recuperará el valor enviado en el controlador.
Los hashes pueden anidarse tantos niveles como sea necesario, por ejemplo:
<input id="person_address_city" name="person[address][city]" type="text" value="New York"/>
Lo anterior resultará en el hash params
siendo
{ 'person' => { 'address' => { 'city' => 'New York' } } }
La otra estructura es un Array. Normalmente Rails ignora los nombres de parámetros duplicados, pero si el nombre del parámetro termina con un conjunto vacío de corchetes []
, entonces los parámetros se acumularán en un Array.
Por ejemplo, si deseas que los usuarios puedan ingresar múltiples números de teléfono, podrías colocar esto en el formulario:
<input name="person[phone_number][]" type="text"/>
<input name="person[phone_number][]" type="text"/>
<input name="person[phone_number][]" type="text"/>
Esto resultaría en params[:person][:phone_number]
siendo un array que contiene los números de teléfono enviados:
{ 'person' => { 'phone_number' => ['555-0123', '555-0124', '555-0125'] } }
8.2 Combinando Arrays y Hashes
Puedes mezclar y combinar estos dos conceptos. Un elemento de un hash podría ser un array, como en el ejemplo anterior, el hash params[:person]
tiene una clave llamada [:phone_number]
cuyo valor es un array.
También puedes tener un array de hashes. Por ejemplo, puedes crear cualquier número de direcciones repitiendo el siguiente fragmento de formulario:
<input name="person[addresses][][line1]" type="text"/>
<input name="person[addresses][][line2]" type="text"/>
<input name="person[addresses][][city]" type="text"/>
<input name="person[addresses][][line1]" type="text"/>
<input name="person[addresses][][line2]" type="text"/>
<input name="person[addresses][][city]" type="text"/>
Esto resultaría en params[:person][:addresses]
siendo un array de hashes. Cada hash en el array tendrá las claves line1
, line2
, y city
, algo así:
{ 'person' =>
{ 'addresses' => [
{ 'line1' => '1000 Fifth Avenue',
'line2' => '',
'city' => 'New York'
},
{ 'line1' => 'Calle de Ruiz de Alarcón',
'line2' => '',
'city' => 'Madrid'
}
]
}
}
Es importante notar que mientras los hashes pueden anidarse arbitrariamente, solo se permite un nivel de "arrayidad". Los arrays generalmente pueden ser reemplazados por hashes. Por ejemplo, en lugar de un array de objetos de modelo, puedes tener un hash de objetos de modelo clave por su id o similar.
ADVERTENCIA: Los parámetros de array no funcionan bien con el ayudante check_box
. Según la especificación HTML, las casillas de verificación no marcadas no envían ningún valor. Sin embargo, a menudo es conveniente que una casilla de verificación siempre envíe un valor. El ayudante check_box
simula esto creando un input oculto auxiliar con el mismo nombre. Si la casilla de verificación no está marcada, solo se envía el input oculto. Si está marcada, entonces se envían ambos, pero el valor enviado por la casilla de verificación tiene prioridad. Hay una opción include_hidden
que puede establecerse en false
si deseas omitir este campo oculto. Por defecto, esta opción es true
.
8.3 Hashes con un Índice
Digamos que deseas renderizar un formulario con un conjunto de campos para cada una de las direcciones de una persona. El ayudante [fields_for
][] con su opción :index
puede ayudar:
<%= form_with model: @person do |person_form| %>
<%= person_form.text_field :name %>
<% @person.addresses.each do |address| %>
<%= person_form.fields_for address, index: address.id do |address_form| %>
<%= address_form.text_field :city %>
<% end %>
<% end %>
<% end %>
Suponiendo que la persona tenga dos direcciones con IDs 23 y 45, el formulario anterior renderizaría esta salida:
<form accept-charset="UTF-8" action="/people/1" method="post">
<input name="_method" type="hidden" value="patch" />
<input id="person_name" name="person[name]" type="text" />
<input id="person_address_23_city" name="person[address][23][city]" type="text" />
<input id="person_address_45_city" name="person[address][45][city]" type="text" />
</form>
Lo que resultará en un hash params
que se ve así:
{
"person" => {
"name" => "Bob",
"address" => {
"23" => {
"city" => "París"
},
"45" => {
"city" => "Londres"
}
}
}
}
Todos los inputs del formulario se asignan al hash "person"
porque llamamos a fields_for
en el form builder person_form
. Además, al especificar index: address.id
, renderizamos el atributo name
de cada input de ciudad como person[address][#{address.id}][city]
en lugar de person[address][city]
. De esta manera, puedes saber qué registros Address
deben modificarse al procesar el hash params
.
Puedes encontrar más detalles sobre la opción de índice de fields_for
en los documentos de la API.
9 Construyendo Formularios Complejos
A medida que tu aplicación crece, es posible que necesites crear formularios más complejos, más allá de editar un solo objeto. Por ejemplo, al crear una Person
puedes permitir que el usuario cree múltiples registros Address
(casa, trabajo, etc.) dentro del mismo formulario. Al editar un registro Person
más tarde, el usuario debería poder agregar, eliminar o actualizar direcciones también.
9.1 Configurando el Modelo para Atributos Anidados
Para editar un registro asociado para un modelo dado (Person
en este caso), Active Record proporciona soporte a nivel de modelo a través del método accepts_nested_attributes_for
:
class Person < ApplicationRecord
has_many :addresses, inverse_of: :person
accepts_nested_attributes_for :addresses
end
class Address < ApplicationRecord
belongs_to :person
end
Esto crea un método addresses_attributes=
en Person
que te permite crear, actualizar y destruir direcciones.
9.2 Formularios Anidados en la Vista
El siguiente formulario permite a un usuario crear una Person
y sus direcciones asociadas.
<%= form_with model: @person do |form| %>
Direcciones:
<ul>
<%= form.fields_for :addresses do |addresses_form| %>
<li>
<%= addresses_form.label :kind %>
<%= addresses_form.text_field :kind %>
<%= addresses_form.label :street %>
<%= addresses_form.text_field :street %>
...
</li>
<% end %>
</ul>
<% end %>
Cuando una asociación acepta atributos anidados, fields_for
renderiza su bloque una vez por cada elemento de la asociación. En particular, si una persona no tiene direcciones, no se renderiza nada.
Un patrón común es que el controlador construya uno o más hijos vacíos para que al menos un conjunto de campos se muestre al usuario. El ejemplo a continuación resultaría en 2 conjuntos de campos de dirección siendo renderizados en el formulario de nueva persona.
Por ejemplo, el form_with
anterior con este cambio:
def new
@person = Person.new
2.times { @person.addresses.build }
end
Generará el siguiente HTML:
<form action="/people" accept-charset="UTF-8" method="post"><input type="hidden" name="authenticity_token" value="lWTbg-4_5i4rNe6ygRFowjDfTj7uf-6UPFQnsL7H9U9Fe2GGUho5PuOxfcohgm2Z-By3veuXwcwDIl-MLdwFRg" autocomplete="off">
Direcciones:
<ul>
<li>
<label for="person_addresses_attributes_0_kind">Tipo</label>
<input type="text" name="person[addresses_attributes][0][kind]" id="person_addresses_attributes_0_kind">
<label for="person_addresses_attributes_0_street">Calle</label>
<input type="text" name="person[addresses_attributes][0][street]" id="person_addresses_attributes_0_street">
...
</li>
<li>
<label for="person_addresses_attributes_1_kind">Tipo</label>
<input type="text" name="person[addresses_attributes][1][kind]" id="person_addresses_attributes_1_kind">
<label for="person_addresses_attributes_1_street">Calle</label>
<input type="text" name="person[addresses_attributes][1][street]" id="person_addresses_attributes_1_street">
...
</li>
</ul>
</form>
El fields_for
produce un form builder. Los nombres de los parámetros serán lo que accepts_nested_attributes_for
espera. Por ejemplo, al crear una persona con 2 direcciones, los parámetros enviados en params
se verían así:
{
'person' => {
'name' => 'John Doe',
'addresses_attributes' => {
'0' => {
'kind' => 'Casa',
'street' => '221b Baker Street'
},
'1' => {
'kind' => 'Oficina',
'street' => '31 Spooner Street'
}
}
}
}
El valor real de las claves en el hash :addresses_attributes
no es importante. Pero necesitan ser cadenas de enteros y diferentes para cada dirección.
Si el objeto asociado ya está guardado, fields_for
autogenera un input oculto con el id
del registro guardado. Puedes desactivar esto pasando include_id: false
a fields_for
.
{
'person' => {
'name' => 'John Doe',
'addresses_attributes' => {
'0' => {
'id' => 1,
'kind' => 'Casa',
'street' => '221b Baker Street'
},
'1' => {
'id' => '2',
'kind' => 'Oficina',
'street' => '31 Spooner Street'
}
}
}
}
9.3 Permitiendo Parámetros en el Controlador
Como de costumbre, necesitas declarar los parámetros permitidos en el controlador antes de pasarlos al modelo:
def create
@person = Person.new(person_params)
# ...
end
private
def person_params
params.require(:person).permit(:name, addresses_attributes: [:id, :kind, :street])
end
9.4 Eliminando Objetos Asociados
Puedes permitir que los usuarios eliminen objetos asociados pasando allow_destroy: true
a accepts_nested_attributes_for
class Person < ApplicationRecord
has_many :addresses
accepts_nested_attributes_for :addresses, allow_destroy: true
end
Si el hash de atributos para un objeto contiene la clave _destroy
con un valor que evalúa como true
(por ejemplo, 1
, '1'
, true
, o 'true'
), entonces el objeto será destruido. Este formulario permite a los usuarios eliminar direcciones:
<%= form_with model: @person do |form| %>
Direcciones:
<ul>
<%= form.fields_for :addresses do |addresses_form| %>
<li>
<%= addresses_form.check_box :_destroy %>
<%= addresses_form.label :kind %>
<%= addresses_form.text_field :kind %>
...
</li>
<% end %>
</ul>
<% end %>
El HTML para el campo _destroy
:
<input type="checkbox" value="1" name="person[addresses_attributes][0][_destroy]" id="person_addresses_attributes_0__destroy">
También necesitas actualizar los parámetros permitidos en tu controlador para incluir el campo _destroy
:
def person_params
params.require(:person).
permit(:name, addresses_attributes: [:id, :kind, :street, :_destroy])
end
9.5 Previniendo Registros Vacíos
A menudo es útil ignorar conjuntos de campos que el usuario no ha llenado. Puedes controlar esto pasando un proc :reject_if
a accepts_nested_attributes_for
. Este proc se llamará con cada hash de atributos enviado por el formulario. Si el proc devuelve true
, entonces Active Record no construirá un objeto asociado para ese hash. El ejemplo a continuación solo intenta construir una dirección si el atributo kind
está establecido.
class Person < ApplicationRecord
has_many :addresses
accepts_nested_attributes_for :addresses, reject_if: lambda { |attributes| attributes['kind'].blank? }
end
Como conveniencia, puedes pasar en su lugar el símbolo :all_blank
, que creará un proc que rechazará registros donde todos los atributos estén en blanco, excluyendo cualquier valor para _destroy
.
10 Formularios para Recursos Externos
Los ayudantes de formularios de Rails pueden usarse para construir un formulario para enviar datos a un recurso externo. Si la API externa espera un authenticity_token
para el recurso, este puede pasarse como un parámetro authenticity_token: 'your_external_token'
a form_with
:
<%= form_with url: 'http://farfar.away/form', authenticity_token: 'external_token' do %>
Contenido del formulario
<% end %>
En otras ocasiones, los campos que pueden usarse en el formulario están limitados por una API externa y puede ser indeseable generar un authenticity_token
. Para no enviar un token, puedes pasar false
a la opción :authenticity_token
:
<%= form_with url: 'http://farfar.away/form', authenticity_token: false do %>
Contenido del formulario
<% end %>
11 Usando Ayudantes de Etiqueta sin un Form Builder
En caso de que necesites renderizar campos de formulario fuera del contexto de un form builder, Rails proporciona ayudantes de etiqueta para elementos de formulario comunes. Por ejemplo, check_box_tag
:
<%= check_box_tag "accept" %>
Salida:
<input type="checkbox" name="accept" id="accept" value="1" />
Generalmente, estos ayudantes tienen el mismo nombre que sus contrapartes de form builder más un sufijo _tag
. Para una lista completa, consulta la documentación de la API de FormTagHelper
.
12 Usando form_tag
y form_for
Antes de que se introdujera form_with
en Rails 5.1, su funcionalidad estaba dividida entre form_tag
y form_for
. Ambos ahora están suavemente obsoletos a favor de form_with
.
Comentarios
Se te anima a ayudar a mejorar la calidad de esta guía.
Por favor contribuye si ves algún error tipográfico o errores fácticos. Para comenzar, puedes leer nuestra sección de contribuciones a la documentación.
También puedes encontrar contenido incompleto o cosas que no están actualizadas. Por favor agrega cualquier documentación faltante para main. Asegúrate de revisar Guías Edge primero para verificar si los problemas ya están resueltos o no en la rama principal. Revisa las Guías de Ruby on Rails para estilo y convenciones.
Si por alguna razón detectas algo que corregir pero no puedes hacerlo tú mismo, por favor abre un issue.
Y por último, pero no menos importante, cualquier tipo de discusión sobre la documentación de Ruby on Rails es muy bienvenida en el Foro oficial de Ruby on Rails.