我正在使用Rails 4.1中的枚举来跟踪葡萄酒的颜色。
Wine.rb
class Wine < ActiveRecord::Base
enum color: [:red, :white, :sparkling]
end
在我看来,我生成一个选择,以便用户可以选择具有特定颜色的葡萄酒
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将颜色解释为整数而不是字符串?
答案 0 :(得分:188)
好吧,显然,你不应该发送要保存的枚举的整数值。您应该发送枚举的文本值。
我将输入更改为以下内容:
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>
值来自&#34; 0&#34; to&#34; red&#34;现在我们已经全部准备好了。
如果你正在使用普通的ol&#39; rails text_field it&#39; s:
f.select :color, Wine.colors.keys.to_a
如果您想拥有干净的人类可读属性,您也可以这样做:
f.select :color, Wine.colors.keys.map { |w| [w.humanize, w] }
答案 1 :(得分:28)
无需将枚举哈希值转换为to_a
的数组。这足够了:
f.select :color, Wine.colors.map { |key, value| [key.humanize, key] }
答案 2 :(得分:9)
对于人类可读,已接受的解决方案对我没有用,但我能够让它像这样工作:
<%= f.select(:color, Wine.colors.keys) %>
这是最干净的,但我真的需要将我的钥匙人性化:
workingButton.setStyleName(BaseTheme.BUTTON_LINK);
workingButton.setIcon(new FileResource(new File(basepath + "help.png")));
答案 3 :(得分:8)
我刚刚整理了一个我想分享的EnumHelper,以帮助那些需要更多自定义枚举标签和区域设置的用户。
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}"), key]
}
end
end
在您的语言区域中:
en:
activerecord:
enums:
wine:
color:
red: "Red Wine"
white: "White Wine"
在您的观点中:
<%= f.select(:color, options_for_enum(@wine, :color)) %>
答案 4 :(得分:5)
如果您在Rails 4中使用枚举,则只需致电Model.enums
:
f.select :color, Wine.colors.keys
创建HTML:
<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
答案 5 :(得分:3)
这是对我有用的Rails 4 +:
class Contract < ApplicationRecord
enum status: { active: "active",
ended: "active",
on_hold: "on_hold",
terminated: "terminated",
under_review: "under_review" ,
unknown: "unknown"
}
end
在my _form.html.erb
中,我有这个:
<div class="field">
<%= form.select :status, Contract.statuses.keys, {}%>
</div>
添加记录后从控制台进行测试:
2.3.0 :001 > Contract.last.status
Contract Load (0.2ms) SELECT "contracts".* FROM "contracts" ORDER BY "contracts"."id" DESC LIMIT ? [["LIMIT", 1]]
=> "active"
答案 6 :(得分:2)
如果你需要根据枚举键处理i18n,你可以使用:
<%= f.select :color, Wine.colors.keys.map {|key| [t("wine.#{key}"), key]} %>
在翻译中你可以设置颜色:
wine:
red: Red
white: White
答案 7 :(得分:1)
这是我的解决方案(我的角色在其中有下划线,如&#34; sales_rep&#34;),由于某种原因,这就是我需要一个空白选项才能工作(使用simpleform?):
在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
然后以我的形式:
<%= f.input :role, collection: enum_collection_for_select(User.roles), selected: @user.role %>
答案 8 :(得分:0)
对我来说,以下方法也有效:
= f.input :color, collection: Wine.colors.keys.map{ |key| [key.humanize, key] }, include_blank: false