Слияние сильных параметров Rails или условные сильные параметры

Основываясь на авторизации пользователей, я хотел бы очистить параметры, включив в них те, которые им разрешено обновлять. Для одной модели есть 5 разных ролей, и я бы не стал перечислять 25 возможных комбинаций и называть

params.require(:asset).permit(вещи)

25 раз

Есть ли способ «построить» сильные параметры? Единственный возможный способ, который я нашел, - это "слияние", но я не могу заставить его работать

Вот где я нахожусь:

def update_params
    p = params.require(:asset)
    if can? :update, Asset
      p.merge params.require(:asset).permit(:code, :description)
    end
    if can? :update, Ability::THING1
      p.merge params.require(:asset).permit(:some_nested_stuff => [:id, :quantity, :_destroy],
                   :some_other_nested_stuff => [:id, :quantity, :_destroy])
    end
    if can? :update, Ability::THING2
      p.merge params.require(:asset).permit(more_nested_stuff: [:id, :date, :note])
    end
    if can? :update, AssetNote
      p.merge params.require(:asset).permit(notes_attributes: [:id, :note, :_destroy])
    end
    p
  end

При этом я получаю «ForbiddenAttributesError» вместо того, чтобы просто выбрасывать атрибуты.


person James R    schedule 03.12.2015    source источник


Ответы (2)


Слияние - это путь, насколько я знаю. С другой стороны, ваше слияние не работает, потому что .merge не обновляет хэш p, вы можете либо сделать p = p.merge, либо использовать p.merge!, который изменяет p.

Кроме того, в зависимости от того, насколько вложенными являются ваши модели, вам может понадобиться .deep_merge вместо merge.

Надеюсь, это поможет.

person nbermudezs    schedule 03.12.2015
comment
Ваше здоровье. Я понял это сразу после того, как разместил вопрос и внес изменения, но у меня все еще нет любви :( Та же ошибка. Также пробовал deep_merge! - person James R; 03.12.2015
comment
У вас есть соответствующие accepts_nested_attributes_for в ваших моделях? - person nbermudezs; 03.12.2015
comment
Да, все работает нормально, прежде чем добавлять какую-либо дезинфекцию. Раньше это был просто один большой params.require(blah).permit(lots_of_blah) - person James R; 03.12.2015
comment
Кажется, он работает после создания массива и передачи его для разрешения. Я не уверен, является ли это передовым решением или нет - person James R; 03.12.2015

Похоже, это решение работает - просто создайте массив и передайте его для разрешения. Я понятия не имею, будет ли это считаться лучшей практикой

def update_params
    a = []
    if can? :update, Asset
      a += [:code, :description]
    end
    if can? :update, Ability::THING1
      a += [:some_nested_stuff => [:id, :quantity, :_destroy],
                   :some_other_nested_stuff => [:id, :quantity, :_destroy]]
    end
    ......
    params.require(:asset).permit(a)
  end
person James R    schedule 03.12.2015
comment
Просто любопытно, полученный хэш похож на тот, который был сгенерирован с помощью merge? - person nbermudezs; 03.12.2015
comment
Я не проверял. Может быть, я вызывал слияние с неправильными аргументами, поэтому это не сработало? - person James R; 03.12.2015
comment
Да, определенно возможно. Это могло вызвать ошибку ForbiddenAttributesError. В любом случае, рад, что вы нашли способ заставить его работать. - person nbermudezs; 03.12.2015