Rails 5: collection_check_boxes из enum (хеш) - PullRequest
0 голосов
/ 10 июня 2019

Как создать collection_check_boxes из хэша enum:

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"

Я получил правильное проверенное разрешение из базы данных! Yay !!

Однако при отправке формы это параметры:

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 голосов
/ 20 июня 2019

, если вы используете 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

0 голосов
/ 10 июня 2019

И с неопределенной ошибкой метода, попробуйте поместить метод enum в метод.

def permissions
    enum permission: {
       read_contact: 0,
       write_contact: 1,
       read_message: 2,
       write_message: 3
    }
end
0 голосов
/ 17 июня 2019

Если вы хотите вложенную форму.Вы можете попробовать это.

В файле 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"}}

0 голосов
/ 10 июня 2019

С помощью Strong Parameters вам нужно сообщить Rails, когда вы ожидаете массив скалярных значений; в противном случае он ожидает только одно значение.

Синтаксис, который вам нужен здесь:

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

Если в будущем вам понадобятся определенные ключи в вашем массиве roles, вы также можете сделать:

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

Это позволило бы любое количество ролей, но каждая роль могла бы иметь только ключи role_id и name.

Надеюсь, это поможет; Я сам недавно с этим боролся.

...