【问题标题】:Rails 5: collection_check_boxes from enum (hash)Rails 5:来自枚举的collection_check_boxes(散列)
【发布时间】:2019-06-10 09:45:56
【问题描述】:

如何从散列的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 #&lt;User:0x00007...&gt;

如果我尝试:

= 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 中得到了什么:

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

【问题讨论】:

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


    【解决方案1】:

    使用强参数,您需要告诉 Rails 什么时候需要一个标量值数组;否则,它只需要一个值。

    这里需要的语法是:

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

    如果您以后需要在 roles 数组中添加特定键,您也可以这样做:

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

    这将允许任意数量的角色,但每个角色只能拥有role_idname 键。

    希望这会有所帮助;我最近自己也在为此苦苦挣扎。

    【讨论】:

    • 感谢您的建议,我通过了 Unpermitted 参数。但是,保存时出现错误:ActiveRecord::AssociationTypeMismatch - UserRole(#70216659953380) expected, got "0" which is an instance of String(#70216944287200):
    • 认为这里的问题是您试图传递权限而不是角色。对于嵌套属性,您通常会有一个子表单:guides.rubyonrails.org/form_helpers.html#nested-forms
    • 还有@Steve:(roles: {:role_id, :name}) 应该是数组[],我用{} 测试过,但不起作用
    • 我已经更新了帖子并按照您的建议使用了nested-forms! @史蒂夫希尔
    【解决方案2】:

    如果出现未定义的方法错误,请尝试将枚举声明放入方法中。

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

    【讨论】:

      【解决方案3】:

      如果你想嵌套表格。你可以试试这个。

      在 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"=&gt;{"0"=&gt;{"permission"=&gt;"1"}, "3"=&gt;{"permission"=&gt;"2"}}

      【讨论】:

        【解决方案4】:

        如果您将 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 的文档中看到

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-03-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多