保存从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