Guardar enumeración de select en Rails 4.1
Estoy usando las enumeraciones en Rails 4.1 para hacer un seguimiento de los colores del vino.
Vino.rb
class Wine < ActiveRecord::Base
enum color: [:red, :white, :sparkling]
end
En mi opinión, genero un select para que el usuario pueda seleccionar un vino con un determinado color
f.input :color, :as => :select, :collection => Wine.colors
Esto genera el siguiente HTML:
<select id="wine_color" name="wine[color]">
<option value=""></option>
<option value="0">red</option>
<option value="1">white</option>
<option value="2">sparkling</option>
</select>
Sin embargo, al enviar el formulario, recibo un error de argumento que indica '1' is not a valid color
. Me doy cuenta de que esto es porque color
debe ser igual a 1
y no "1"
.
¿Hay una manera de forzar los rieles para interpretar el color como un entero en lugar de una cadena?
7 answers
Muy bien, por lo que aparentemente, no debe enviar el valor entero de la enumeración que se guardará. Debe enviar el valor de texto de la enumeración.
Cambié la entrada para que fuera la siguiente:
f.input :color, :as => :select, :collection => Wine.colors.keys.to_a
Que generó el siguiente HTML:
<select id="wine_color" name="wine[color]">
<option value=""></option>
<option value="red">red</option>
<option value="white">white</option>
<option value="sparkling">sparkling</option>
</select>
Los valores pasaron de "0" a "rojo" y ahora estamos listos.
Si estás usando un campo de texto de rails normal es:
f.select :color, Wine.colors.keys.to_a
Si desea tener atributos legibles por humanos limpios, también puede do:
f.select :color, Wine.colors.keys.map { |w| [w.humanize, w] }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-18 21:32:19
No es necesario convertir el hash de enumeración en matriz con to_a
. Esto es suficiente:
f.select :color, Wine.colors.map { |key, value| [key.humanize, key] }
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-06 10:37:26
La solución aceptada no funcionó para mí para el legible por humanos , pero pude hacer que funcionara de la siguiente manera:
<%= f.select(:color, Wine.colors.keys.map {|key| [key.humanize, key]}) %>
Esta era la más limpia, pero realmente necesitaba humanizar mis llaves:
<%= f.select(:color, Wine.colors.keys) %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-02 21:11:35
Acabo de armar un EnumHelper que pensé que compartiría para ayudar a las personas que necesitan etiquetas de enumeración más personalizadas y locales para su enum selects.
module EnumHelper
def options_for_enum(object, enum)
options = enums_to_translated_options_array(object.class.name, enum.to_s)
options_for_select(options, object.send(enum))
end
def enums_to_translated_options_array(klass, enum)
klass.classify.safe_constantize.send(enum.pluralize).map {
|key, value| [I18n.t("activerecord.enums.#{klass.underscore}.#{enum}.#{key}").humanize, key]
}
end
end
En su configuración regional:
en:
activerecord:
enums:
wine:
color:
red: "Red Wine"
white: "White Wine"
En sus puntos de vista:
<%= f.select(:color, options_for_enum(@wine, :color)) %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-31 15:39:48
Si usa enum en Rails 4, simplemente llame a Model.enums
:
f.select :color, Wine.colors.keys
Para crear HTML:
<select name="f[color]" id="f_color">
<option value="red">red</option>
<option value="white">white</option>
<option value="sparkling"> sparkling </option>
</select>
O añadir método en el controlador:
def update_or_create
change_enum_to_i
....
end
def change_enum_to_i
params[:f]["color"] = params[:f]["color"].to_i
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-03 09:07:00
Si necesita manejar el i18n basado en las claves enum, puede usar:
<%= f.select :color, Wine.colors.keys.map {|key| [t("wine.#{key}"), key]} %>
Y en las traducciones puedes establecer los colores:
wine:
red: Red
white: White
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-01 15:37:39
Aquí está mi solución (mis roles tienen guiones bajos en ellos como "sales_rep"), y por alguna razón así fue como necesitaba obtener una opción en blanco para trabajar (con simpleform?):
En la solicitud de ayuda:
def enum_collection_for_select(attribute, include_blank = true)
x = attribute.map { |r| [r[0].titleize, r[0]] }
x.insert(0,['', '']) if include_blank == true
x
end
Entonces en mi forma:
<%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-24 19:42:48