从表单中选择枚举以设置角色

DDD*_*DDD 14 enums ruby-on-rails devise ruby-on-rails-4 railsapps

Ruby on Rails 4.1

我正在使用具有枚举角色的Devise.它在创建用户时当前设置了defualt角色.我想在表单中添加一个字段,用于创建用户以设置枚举角色.

我读过这篇文章,但没有说明如何利用新角色.

这是User类

devise :database_authenticatable, :registerable, :confirmable,
     :recoverable, :rememberable, :trackable, :validatable
enum role: [:user, :vip, :admin, :developer, :marketing, :support, :translator]
after_initialize :set_default_role, :if => :new_record?

def set_default_role
  self.role ||= :user
end
Run Code Online (Sandbox Code Playgroud)

这是我尝试选择一个枚举角色的表单的一部分:

<div class="form-group">
  <%= f.collection_select :role, User.roles, :id, :enum, {prompt: "Select a role"}, {class: "form-control input-lg"} %>
</div>
Run Code Online (Sandbox Code Playgroud)

错误:

NoMethodError - undefined method `enum' for ["user", 0]:Array:
actionview (4.1.1) lib/action_view/helpers/form_options_helper.rb:761:in `value_for_collection'
Run Code Online (Sandbox Code Playgroud)

我之前从未使用过enum,文档也没有证明是有帮助的.如何显示枚举选项?

Dan*_*hoe 34

首先,enum不是属性的名称.属性的名称是role.

看看rails- devise-pundit示例应用程序,特别是文件app/views/users/_user.html.erb,它是创建表单以允许管理员更改用户角色的部分.我怀疑你是否想要使用collection_selectfor helper(如果你有一个单独的Role模型,这是合适的).相反,普通的select表单助手将起作用.

这是一个硬编码角色选项的简单示例:

<%= f.select(:role, [['User', 'user'], ['Vip', 'vip'], ['Admin', 'admin']]) %>
Run Code Online (Sandbox Code Playgroud)

这是一个更好的示例,可以避免在表单中对角色进行硬编码:

<%= f.select(:role, User.roles.keys.map {|role| [role.titleize,role]}) %>
Run Code Online (Sandbox Code Playgroud)

该语句从User模型获取角色数组,并使用该map方法构造键值对数组.


Moh*_*mad 9

由于您使用的是Rails 4或更高版本,因此枚举更简单.

鉴于以下枚举:

enum role: {
  admin: 1
}
Run Code Online (Sandbox Code Playgroud)

枚举期望HTML选项属性value为枚举键:

<option value="admin"> <!-- As opposed to: <option value="1"> -->
Run Code Online (Sandbox Code Playgroud)

知道这一点,你可以传入枚举键.

<%= f.select :role, User.roles.keys, {}, class: 'user-roles-select' %>
Run Code Online (Sandbox Code Playgroud)

然后使用CSS您可以修改外观.

.user-roles-select option {
  text-transform: capitalize;
}
Run Code Online (Sandbox Code Playgroud)


Yan*_*oto 7

collection_selectenums 一起使用的最干净的方法如下:

f.collection_select :diet_preference, User.roles.map{ |dp| [dp.first, dp.first.humanize] }, :first, :second
Run Code Online (Sandbox Code Playgroud)

  • 只是为了线程。他的意思是:`f.collection_select :diet_preference, User.roles.keys.map{ |dp| [dp, dp.人性化] }` (3认同)