Guardar enumeración de select en Rails 4.1

Estoy usando las enumeraciones en Rails 4.1 para realizar un seguimiento de los colores del vino.

Wine.rb

class Wine < ActiveRecord::Base enum color: [:red, :white, :sparkling] end 

En mi opinión, genero una selección para que el usuario pueda seleccionar un vino con un cierto color

 f.input :color, :as => :select, :collection => Wine.colors 

Esto genera el siguiente HTML:

   red white sparkling  

Sin embargo, al enviar el formulario, recibo un error de argumento que indica que '1' is not a valid color . Me doy cuenta de que esto se debe a que el color debe ser igual a 1 y no a "1" .

¿Hay alguna manera de forzar a Rails a interpretar el color como un entero en lugar de una cadena?

De acuerdo, aparentemente, no deberías enviar el valor entero de la enumeración para guardar. Debe enviar el valor de texto de la enumeración.

Cambié la entrada para que sea la siguiente:

f.input :color, :as => :select, :collection => Wine.colors.keys.to_a

Que generó el siguiente HTML:

  

Los valores pasaron de “0” a “rojo” y ahora estamos listos.


Si está utilizando un campo de texto de ol ‘rails normal, es:

f.select :color, Wine.colors.keys.to_a


Si desea tener atributos limpios legibles para el ser humano, también puede hacer:

f.select :color, Wine.colors.keys.map { |w| [w.humanize, w] }

No es necesario convertir el enum hash al array con to_a . Esto es suficiente

 f.select :color, Wine.colors.map { |key, value| [key.humanize, key] } 

La solución aceptada no funcionó para mí para la lectura humana , pero pude hacer que funcionara así:

 <%= f.select(:color, Wine.colors.keys.map {|key| [key.humanize, key]}) %> 

Este fue el más limpio, pero realmente necesitaba humanizar mis llaves:

 <%= f.select(:color, Wine.colors.keys) %> 

Acabo de armar un EnumHelper que pensé que compartiría para ayudar a las personas que necesitan tags enum más personalizadas y configuraciones regionales para su enum selecciona.

 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 tu localidad:

  en: activerecord: enums: wine: color: red: "Red Wine" white: "White Wine" 

En tus puntos de vista:

  <%= f.select(:color, options_for_enum(@wine, :color)) %> 

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 

Si usa enum en Rails 4, simplemente llame a Model.enums :

 f.select :color, Wine.colors.keys 

Para crear HTML:

  

O agregue el 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 

Aquí está mi solución (mis roles se destacan en ellos como “sales_rep”), y por alguna razón, así era como necesitaba obtener una opción en blanco para trabajar (¿con la forma simple?):

En ApplicationHelper:

 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 %>