Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 从表单中选择枚举以设置角色_Ruby On Rails_Ruby On Rails 4_Devise_Enums_Railsapps - Fatal编程技术网

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

Ruby on rails 从表单中选择枚举以设置角色,ruby-on-rails,ruby-on-rails-4,devise,enums,railsapps,Ruby On Rails,Ruby On Rails 4,Devise,Enums,Railsapps,RubyonRails 4.1 我正在使用带有enum角色的designe。它当前在创建用户时设置解除角色。我想在表单中添加一个字段,用于创建设置枚举角色的用户 我读过,但没有说如何利用新角色 这是用户类 devise :database_authenticatable, :registerable, :confirmable, :recoverable, :rememberable, :trackable, :validatable enum role: [:user, :vip,

RubyonRails 4.1

我正在使用带有enum角色的designe。它当前在创建用户时设置解除角色。我想在表单中添加一个字段,用于创建设置枚举角色的用户

我读过,但没有说如何利用新角色

这是用户类

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
这是表单的一部分,我尝试使用select来选择枚举角色:

<div class="form-group">
  <%= f.collection_select :role, User.roles, :id, :enum, {prompt: "Select a role"}, {class: "form-control input-lg"} %>
</div>
我以前从未使用过enum,因此没有任何帮助。如何使枚举选项显示

首先,enum不是属性的名称。该属性的名称为role

看一看示例应用程序,特别是文件app/views/users/_user.html.erb,它是一个创建表单以允许管理员更改用户角色的部分。如果你有一个单独的角色模型,我怀疑你是否想使用一个适合你的助手集合。取而代之的是,一个普通的select表单帮助器将起作用

下面是一个简单的示例,对角色选项进行硬编码:

<%= f.select(:role, [['User', 'user'], ['Vip', 'vip'], ['Admin', 'admin']]) %>
下面是一个更好的示例,可以避免对表单中的角色进行硬编码:

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

该语句从用户模型中获取一个角色数组,并使用map方法构造一个键值对数组。

为了将collection_select与Enum一起使用,我使用的最干净的方法如下:

    class Child < ApplicationRecord
       enum year: {
          Infant: 'Infant',
          '2-5_years': '2_to_5_years',
          '5-8_years': '5_to_8_years',
          '8-10_years': '8_to_10 years',
          'More_than_10_years': 'More_than_10_years'
       }
       AGE_YEARS = Child.years.map { |k, v| [k.humanize, v] }
     }
f、 集合_选择:饮食_偏好,用户.角色.映射{| dp |[dp.first,dp.first.humanize]},:第一,:第二
由于您使用的是Rails 4或更高版本,枚举就更不复杂了

给定以下枚举:

enum role: {
  admin: 1
}
枚举期望HTML选项属性值为枚举键:

<option value="admin"> <!-- As opposed to: <option value="1"> -->

下面是我如何做到的,包括国际化和排序,以及自动选择当前的用户角色(如果已经定义)。 它假定您有一个区域设置文件,其中roles:category包含所有枚举角色,例如:

# your locale file
en:
 roles:
  admin: "Administrator"
  mode: "Moderator"


# model user.rb
enum role: { admin: 0, mode: 1 }
ROLES = User.roles.map { |r,| [I18n.t("roles.#{r}"), r] }.sort_by { |r| I18n.t("roles.#{r}") }

# view

<%= f.select :role, User::ROLES, { prompt: t("users.roles.prompt"), selected: @user.role }, { class: "form-control" } %>

由于enum是Rails中整数的包装器,而我想将字符串存储在DB中,因此我执行了以下操作:

    class Child < ApplicationRecord
       enum year: {
          Infant: 'Infant',
          '2-5_years': '2_to_5_years',
          '5-8_years': '5_to_8_years',
          '8-10_years': '8_to_10 years',
          'More_than_10_years': 'More_than_10_years'
       }
       AGE_YEARS = Child.years.map { |k, v| [k.humanize, v] }
     }
并更改了迁移文件,如下所示

class AddYearToChildren < ActiveRecord::Migration[5.0]
  def up
    execute <<-SQL
      CREATE TYPE year AS ENUM ('Infant', '2_5_years', '5_8_years', '8_10_years', 'More_than_10_years');
    SQL
    add_column :children, :year, :year, index: true
  end

  def down
    remove_column :children, :year

    execute <<-SQL
      DROP TYPE year;
    SQL
  end
end
最后,rails db:migrate用于数据库迁移更改


因此,现在可以使用rails enum在DB中存储字符串。

剩下的唯一要做的就是覆盖designe::RegistrationsControllercreate以立即允许角色+1无需覆盖注册控制器。您可以在应用程序控制器中执行此操作。看看我的,我想我是用非懒惰的方式做的。我制作了一个用户:RegistrationController和一个before_过滤器:配置该消毒剂允许的参数。例如:如果我发布了该代码,请注册。您能告诉我这是否是一种安全的方法吗?另一种方法:如果您正在努力映射自己的阵列,您也可以只使用select,它将直接使用它,而不需要调用第一个和第二个。此外,您还可以映射User.roles.keys`而不是User.roles,这样您就不必首先调用它,这需要更多的思考来理解,而不仅仅是为了线程。他的意思是:f.collection_select:diet_preference,User.roles.keys.map{dp |[dp,dp.humanize]}
    class Child < ApplicationRecord
       enum year: {
          Infant: 'Infant',
          '2-5_years': '2_to_5_years',
          '5-8_years': '5_to_8_years',
          '8-10_years': '8_to_10 years',
          'More_than_10_years': 'More_than_10_years'
       }
       AGE_YEARS = Child.years.map { |k, v| [k.humanize, v] }
     }
<%= f.select :age, options_for_select(Child::AGE_YEARS, params[:age]), include_blank: 'Select an age-group.' %>
 rails generate migration AddYearToChildren year:year
class AddYearToChildren < ActiveRecord::Migration[5.0]
  def up
    execute <<-SQL
      CREATE TYPE year AS ENUM ('Infant', '2_5_years', '5_8_years', '8_10_years', 'More_than_10_years');
    SQL
    add_column :children, :year, :year, index: true
  end

  def down
    remove_column :children, :year

    execute <<-SQL
      DROP TYPE year;
    SQL
  end
end