Сильные параметры Rails 4.0.0, похоже, не работают так, как задокументировано

Пример, используемый в документации (http://guides.rubyonrails.org/action_controller_overview.html#strong-parameters) для сильных параметров:

params.require(:person).permit(:name, :age)

Однако это не работает, потому что функция require() возвращает значение параметра, а не другой объект параметра, для которого может быть вызвана функция allow().

$ rails console
1.9.3p286 :005 > params = ActionController::Parameters.new(person: 1, name: "Joe", age: 30)
 => {"person"=>1, "name"=>"Joe", "age"=>30} 
1.9.3p286 :006 > params.require(:person).permit(:name, :age)
NoMethodError: undefined method `permit' for 1:Fixnum
    from (irb):6
    from /Users/jeremyburton/.rvm/gems/ruby-1.9.3-p286/gems/railties-4.0.0/lib/rails/commands/console.rb:90:in `start'
    from /Users/jeremyburton/.rvm/gems/ruby-1.9.3-p286/gems/railties-4.0.0/lib/rails/commands/console.rb:9:in `start'
    from /Users/jeremyburton/.rvm/gems/ruby-1.9.3-p286/gems/railties-4.0.0/lib/rails/commands.rb:64:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'

Кроме того, кажется странным, что require может принимать только 1 параметр. Кажется, что вы должны быть в состоянии сделать:

params.require(:a, :b).permit(:c, :d)

Принимая во внимание, что вам нужно сделать, это:

params.require(:a)
params.require(:b)
params.permit(:a, :b, :c, :d)

что не кажется очень СУХИМ - если параметр требуется, то он по определению разрешен, конечно.

Я что-то упускаю?


person Jeremy Burton    schedule 24.09.2013    source источник


Ответы (1)


Целью require является работа с объектами Rails form_for, при этом хэш параметров будет включать имя объекта, вокруг которого вы оборачиваете форму. Ну вот так:

ActionController::Parameters.new(person: { name: 'Francesco' }).require(:person)

В этом случае form_for был бы обернут вокруг объекта Person. Таким образом, .require(:person) преобразует полученный хэш ({ name: 'Francesco' }) в объект ActionController::Parameters, который может отвечать на .permit. Таким образом, ваш тест просто не имитировал ожидаемый вариант использования параметров.

Кроме того, имеет смысл, что require будет принимать только один аргумент, поскольку вы хотите настроить уникальный метод <attribute>_params для каждого типа объекта, поскольку, опять же, они предназначены для обертки для определенного объекта. Но обычно у вас будет только 1 корневой объект, отправляемый в форму отправки, и подобъекты внутри него.

person pdobb    schedule 24.09.2013
comment
Спасибо. Это имеет смысл. - person Jeremy Burton; 25.09.2013