Rails 5:枚举中的collection_check_boxes(哈希)

时间:2019-06-10 09:45:56

标签: ruby-on-rails enums form-for

如何从散列的enum创建collection_check_boxes:

class User < ApplicationRecord
  has_many :roles, dependent: :destroy
  accepts_nested_attributes_for :roles, allow_destroy: true
end

class Role < ApplicationRecord
  belongs_to :user

  enum permission: {
    read_contact: 0,
    write_contact: 1,
    read_message: 2,
    write_message: 3
  }
end

我尝试了很多方法:

= form_for(@user) do |f|
  = f.collection_check_boxes :permissions, Role.permissions, :last, :first
  = f.submit class: "button"

我得到了undefined method permissions for #<User:0x00007...>

如果我尝试:

= form_for(@user) do |f|
  = f.collection_check_boxes :roles, Role.permissions, :last, :first
  = f.submit class: "button"

用户控制器:

def update
  @user = User.new(user_params)
  if @user.save 
     ...
end

def user_params
  params.require(:user).permit(:roles)
end

我得到了Unpermitted parameter: :roles

尽管查看参数:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "user"=>{"roles"=>["", "1", "2"]}, "commit"=>"Update", "id"=>"3"}

这也是创建检查,如何取消选中删除?

更新:尝试使用@Steve所说的我应该使用嵌套表格

= form_for(@user) do |f|
  = f.fields_for :roles do |ff|
    = ff.collection_check_boxes :permission, Role.permissions, :first, :first
  = f.submit class: "button"

我从数据库获得了正确的检查权限!是的!

但是在发送表单时,这是参数:

Parameters: {"utf8"=>"✓", "authenticity_token"=>"...", "user"=>{"roles_attributes"=>{"0"=>{"permission"=>["", "read_message", "write_message"], "id"=>"18"}}}, "commit"=>"Update", "id"=>"3"}

我在控制器中允许使用Unpermitted parameter: :permission

def user_params
  params.require(:user).permit(roles_attributes: %i[id permission _destroy])
end

我认为参数应该是这样的:

params = { user: {
  roles_attributes: [
    { permission: 'read_message' },
    { permission: 'write_message' },
    ...
  ]
}}

相反,我现在获得的参数是:

params = { user: {
  roles_attributes: [
    { permission: ['', 'read_message', 'write_message' }
    ...
  ]
}}

4 个答案:

答案 0 :(得分:0)

使用Strong Parameters,您需要在期望标量值数组时告诉Rails。否则,它只期望一个值。

您这里需要的语法是:

params.require(:user).permit(roles: [])

如果以后需要在roles数组中有特定的键,也可以执行以下操作:

params.require(:user).permit(roles: {:role_id, :name})

这将允许任何数量的角色,但每个角色仅具有键role_idname

希望这会有所帮助;我本人最近为此感到挣扎。

答案 1 :(得分:0)

并且由于未定义的方法错误,请尝试将枚举decleration放入方法中。

def permissions
    enum permission: {
       read_contact: 0,
       write_contact: 1,
       read_message: 2,
       write_message: 3
    }
end

答案 2 :(得分:0)

如果您想嵌套表格。你可以试试看。

在HTML文件中

- Role.permissions.each do |key, value|
  = f.fields_for :roles, @user.roles.build do |fr|
    = fr.checkbox :permission, {}, value, false

在模型文件中:user.rb

accepts_nested_attributes_for :roles, reject_if:  proc { |attributes| attributes['permission'].blank? }

正确的参数 roles_attributes"=>{"0"=>{"permission"=>"1"}, "3"=>{"permission"=>"2"}}

答案 3 :(得分:0)

如果您将fields_for与nested_attribures一起使用。在具有fields_for的表单中,您必须使用f.check_box才能使此表单可以呈现具有可以按预期生成参数的属性的html

params = { user: {
  roles_attributes: [
    { permission: 'read_message' },
    { permission: 'write_message' },
    ...
  ]
}}

如果您使用ff.collection_check_boxes :permission, Role.permissions, :first, :first,则所有选中的值都将设置在字段permission中,这样参数将是permission: ['', 'read_message', 'write_message']

您可以在collection_check_boxes https://apidock.com/rails/v4.0.2/ActionView/Helpers/FormOptionsHelper/collection_check_boxes的文档中看到