usage rails how enum application ruby-on-rails ruby ruby-on-rails-4 enums

ruby on rails - how - Guardar enumeración de select en Rails 4.1



rails enum migration (7)

Acabo de armar un EnumHelper que pensé que compartiría para ayudar a las personas que necesitan etiquetas 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.downcase}.#{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)) %>

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:

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


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


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:

<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á 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] }


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


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] }


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:

<select name="f[color]" id="f_color"> <option value="red">red</option> <option value="white">white</option> <option value="sparkling"> sparkling </option> </select>

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