保存从select导轨4.1枚举

我使用Rails 4.1中的枚举来跟踪葡萄酒的颜色。

Wine.rb

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

在我看来,我产生了一个select,所以用户可以select具有某种颜色的葡萄酒

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

这将生成以下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> 

但是,提交表单后,我收到一个参数错误,指出'1' is not a valid color 。 我意识到这是因为color必须等于1而不是"1"

有没有办法强制Rails将颜色解释为整数而不是string?

好吧,显然,你不应该发送枚举的整数值来保存。 您应该发送该枚举的文本值。

我改变了input如下:

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

其中生成了以下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> 

值从“0”变为“红色”,现在我们都已经设定好了。


如果你正在使用一个普通的ol轨道text_field它是:

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


如果你想拥有干净的人类可读属性,你也可以这样做:

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

不需要使用to_a将枚举哈希转换为数组。 这足够了:

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

被接受的解决scheme对我来说不适合人类阅读 ,但是我可以像这样工作:

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

这是最干净的,但我真的需要人性化我的钥匙:

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

我只是把一个EnumHelper放在一起,我想我会分享,以帮助那些需要更多自定义枚举标签和语言环境为您的枚举select。

 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: activerecord: enums: wine: color: red: "Red Wine" white: "White Wine" 

在你的看法:

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

如果你需要处理基于枚举键的国际化,你可以使用:

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

并在tranlations你可以设置颜色:

 wine: red: Red white: White 

这是我的解决scheme(我的angular色像“sales_rep”一样在其中强调),出于某种原因,这是我需要得到一个空白选项的工作(与简单?):

在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 

然后以我的forms:

 <%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %> 

如果你在Rails 4中使用枚举,那就调用Model.enums

 f.select :color, Wine.colors.keys 

要创buildHTML:

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

或者在控制器中添加方法:

 def update_or_create change_enum_to_i .... end def change_enum_to_i params[:f]["color"] = params[:f]["color"].to_i end