ruby-on-rails - fields_for - form_with ruby on rails
Ayudantes de formularios personalizados (3)
¿Hay alguna forma de crear un ayudante de formulario personalizado para que en lugar de:
special_field_tag :object, :method
Puedo lograr algo como:
form.special_field :method
@Tilendor, muchas gracias por los punteros. Este es un ejemplo de un ayudante de etiquetas de formulario enum_select
que utiliza las enumeraciones de Rails 4.1 para completar automáticamente las opciones de una etiqueta de selección:
# helpers/application_helper.rb
module ApplicationHelper
class ActionView::Helpers::FormBuilder
# http://.com/a/2625727/1935918
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
def enum_select(name, options = {})
# select_tag "company[time_zone]", options_for_select(Company.time_zones
# .map { |value| [value[0].titleize, value[0]] }, selected: company.time_zone)
select_tag @object_name + "[#{name}]", options_for_select(@object.class.send(name.to_s.pluralize)
.map { |value| [value[0].titleize, value[0]] }, selected: @object.send(name))
end
end
end
La construcción más complicada es @object.class.send(name.to_s.pluralize)
que produce un hash de valores disponibles (por ejemplo, Company.time_zones
). Ponerlo en helpers/application_helper.rb
hace disponible automáticamente. Se utiliza como:
<%= f.label :billing_status %>:
<%= f.enum_select :billing_status %><br />
Nuestra aplicación mostraba números de teléfono en campos de texto, y queríamos omitir el código de país para los números nacionales. Estaba usando formularios de ayuda. Después de leer esto y la fuente de los rieles un poco, llegué a esta solución:
class ActionView::Helpers::FormBuilder
def phone_text_field name, options = {}
value = object.public_send(name).to_s
if value.start_with? "9" # national number
value = value[1..-1]
options["value"] = value
end
text_field name, options
end
end
text_field()
esto en app / helpers / application_helper.rb y lo uso como uso text_field()
helper. Espero que esto ayude a alguien.
Sí, puede agregar a la clase FormBuilder y obtener acceso al objeto pasado a form_for. He hecho esto por muchas cosas: fechas, horarios, medidas, etc. Aquí hay un ejemplo:
class ActionView::Helpers::FormBuilder
include ActionView::Helpers::TagHelper
include ActionView::Helpers::FormTagHelper
include ActionView::Helpers::FormOptionsHelper
include ActionView::Helpers::CaptureHelper
include ActionView::Helpers::AssetTagHelper
# Accepts an int and displays a smiley based on >, <, or = 0
def smile_tag(method, options = {})
value = @object.nil? ? 0 : @object.send(method).to_i
options[:id] = field_id(method,options[:index])
smiley = ":-|"
if value > 0
smiley = ":-)"
elsif smiley < 0
smiley = ":-("
end
return text_field_tag(field_name(method,options[:index]),options) + smiley
end
def field_name(label,index=nil)
output = index ? "[#{index}]" : ''''
return @object_name + output + "[#{label}]"
end
def field_id(label,index=nil)
output = index ? "_#{index}" : ''''
return @object_name + output + "_#{label}"
end
end
Que puedes usar así:
<% form_for @quiz do |f| %>
<%= f.smile_tag(:score) %>
<% end %>
Existen algunas variables de instancia creadas por Rails a las que puede acceder en estos métodos de ayuda:
- @object - el objeto modelo especificado por el formulario
- @object_name - el nombre de clase del objeto
- @template - Creo que es una instancia de ActionView, posiblemente puede omitir todos los elementos que agregué al llamar a los métodos en la plantilla. Aún no lo he intentado.
- @options - opciones pasadas a FormBuilder cuando se crea mediante la llamada form_for
Escribí los métodos field_id y field_name para crear estos atributos en los elementos de entrada HTML de la misma manera que lo hacen los ayudantes regulares, estoy seguro de que hay una forma de vincularse con los mismos métodos que utiliza Rails, pero todavía no lo he encontrado .
El cielo es el límite de lo que puede hacer con estos métodos de ayuda, simplemente devuelven cadenas. Puede crear tablas o páginas HTML completas en una, pero es mejor que tenga una buena razón para hacerlo.
Este archivo debe agregarse en la carpeta app / helpers