Rails 4 Сильные параметры: разрешить все атрибуты?

Я создаю веб-приложение с сильными параметрами Rails 4.

При создании контроллеров административного бэк-офиса мне интересно, как лучше всего разрешить все атрибуты модели?

А пока я написал это:

def user_params 
  params.require(:user).permit(User.fields.keys)
end

Вы думаете, как лучше?


person Nicolas Blanco    schedule 25.12.2012    source источник
comment
Почему? Я делаю такие вещи только в своем административном бэк-офисе, где я доверяю всем пользователям.   -  person Nicolas Blanco    schedule 28.02.2014
comment
просто потому, что вы им доверяете (а вы не должны, но это другая история), оставить все свои данные открытыми для перезаписи - это дыра в безопасности, ожидающая использования   -  person sevenseacat    schedule 28.02.2014
comment
Важным принципом безопасности является идея занесения в белый список того, что вы явно хотите сделать доступным. Явным перечислением вы предотвращаете такие проблемы, как когда вы (коллега) вводите новый ключ в свой код и ожидаете, что он будет доступен только через контроллер при выполнении явных действий. Или, другими словами: придерживайтесь условностей, если у вас нет очень и очень веской причины не делать этого. Почти каждый раз, когда я делал это раньше, я стрелял себе в пол.   -  person bert bruynooghe    schedule 30.05.2014
comment
@sevenseac, по крайней мере, он спрашивает, есть ли способ лучше.   -  person Andrew Grimm    schedule 16.07.2015
comment
@AndrewGrimm: да, но он по-прежнему хочет разрешить все по умолчанию, что небезопасно и полностью сводит на нет смысл сильных параметров.   -  person sevenseacat    schedule 16.07.2015
comment
@sevenseacat, что, если я хочу работать только с некоторыми контроллерами и не хочу вводить все эти ключи?   -  person Anwar    schedule 20.10.2015
comment
@Anwar «потому что я не могу беспокоиться о том, чтобы набирать ключи», - вполне возможно, худшая причина для обхода меры безопасности.   -  person sevenseacat    schedule 21.10.2015


Ответы (4)


На всякий случай, если кому-то это понадобится для Rails 6, даже без привязки модели к вашему контроллеру, вы можете использовать:

before_action :accept_all_params

private

def accept_all_params
  params.permit!
end

Готово, теперь вы можете играть с ???? сколько угодно!

person vvo    schedule 14.01.2020

Вы можете назвать взрывную версию разрешения.

params.require(:user).permit!

README для строгих параметров на Github

Исходный код для справки:

def permit!
  each_pair do |key, value|
    convert_hashes_to_parameters(key, value)
    self[key].permit! if self[key].respond_to? :permit!
  end

  @permitted = true
  self
end
person Damon Aw    schedule 26.12.2012
comment
Кстати, я думаю, что если бы там было что-то вроде permit :all, мне это показалось бы более рельсовым, чем метод взлома, который обычно означает, что получатель изменялся чаще, чем пометка метода как опасного. - person Damon Aw; 27.12.2012
comment
да, но разрешение (: all) выглядит как find (: all) ActiveRecord, который устарел. - person Nicolas Blanco; 27.12.2012
comment
@NicolasBlanco: Я не понимаю, почему permit(:all) выглядит как find(:all). - person David J.; 05.03.2013
comment
@daemonsy: permit(:all) разрешает поле с именем :all. Чтобы заставить этот стиль работать, как вы говорите, Rails пришлось бы сделать особый случай для обработки :all - я думаю, это было бы некрасиво и запутанно. Если бы у вас была колонка с названием «все», вы были бы наверху! Я согласен с тем, что метод взрыва - неоптимальный выбор. Я бы предложил permit_all как лучшую альтернативу, если бы я проектировал API. - person David J.; 05.03.2013
comment
Каждый раз, когда я вижу эту страницу, я немного сожалею о :all комментарии. знак равно permit_all действительно звучит как лучшая альтернатива, чем бэнг. - person Damon Aw; 05.03.2013
comment
Метод взрыва означает пометку метода как опасный - я предполагаю, что именно поэтому они использовали здесь метод взрыва. - person Andrew; 13.03.2013
comment
@ Андрей Верно, но даже в этом случае я думаю, что permit_all! читал бы лучше. Я рад, что эта штука все равно существует. - person mahemoff; 17.01.2014
comment
Как сказано в моих комментариях по самому вопросу, это действительно то, чего вам не следует делать. Вы нарушаете рельсовые условности ... - person bert bruynooghe; 30.05.2014
comment
@daemonsy: Это потому, что у вас искаженное представление о том, что означает взрыв (!) в имени метода. Конечно, для некоторых методов это означает изменение на месте, а не копирование. Но это только один из способов его использования. Фактическое правило таково: метод взрыва (один, заканчивающийся на!) - это метод, который не действует стандартным или ожидаемым образом, поэтому он заслуживает особого внимания или осторожности. Это причина!. - person Lonny Eachus; 11.08.2014
comment
@LonnyEachus, на самом деле, Мац говорит, что: версия с взломом более опасна, чем его аналог без взрыва; обращаться с осторожностью (источник: ruby-forum.com/topic/176830#773946) - person ; 04.05.2016
comment
на самом деле этот метод изменяет состояние объекта на месте, обратите внимание: @permitted = true - person Dr.Strangelove; 21.06.2018

Ответ Skull0inc работает, но вы можете удалить created_at и updated_at. Назначение strong params - перечислить только те атрибуты, которые вы хотите обновить с помощью контроллера. Что-то вроде...

def user_params
  params.require(:user).permit(User.column_names - ["created_at", "updated_at"])
end
person Anthony Sallows    schedule 07.03.2019

Это сработает?

def user_params 
  params.require(:user).permit(User.column_names)
end
person Skull0inc    schedule 13.09.2018