Сбой сильных параметров Rails 4 при создании экземпляров в консоли rails
вероятно, делает что-то глупое здесь, но вот мой основной класс cookie cutter:
class League < ActiveRecord::Base
private
def league_params
params.require(:full_name).permit!
end
end
и при создании нового экземпляра Лиги:
2.0.0-p0 :001 > l = League.new(full_name: 'foo', short_name: 'bar')
WARNING: Can't mass-assign protected attributes for League: full_name, short_name
что именно я делаю неправильно здесь? Это Rails 4.0.0.beta1 build + Ruby 2.0
** обновление **
Теперь я понимаю, что сильные параметры применяются в контроллере сейчас, а не в модели. Первоначальный вопрос остается в силе. Если они разрешены на уровне контроллера, как могу ли я правильно атрибуты белого списка, если я создаю экземпляры в консоли Rails? Не нужно ли мне также использовать attr_accessible
в этом случае также, таким образом, полностью дублируя, какие сильные параметры пытаются "исправить"?
4 ответов
две вещи. The league_params
определение идет в контроллере, а не в модели. И params.require()
должно содержать имя модели, которая должна присутствовать в параметрах, а не в атрибутах. Проверка наличия атрибута по-прежнему должна быть в проверках модели. И убедитесь, что вы действительно хотите разрешить доступ ко всем атрибутам в модели Лиги, прежде чем использовать permit!
. Так, это должно выглядеть так:
class LeaguesController < ApplicationController
private
def league_params
params.require(:league).permit!
end
end
обновление:
да, если вы хотите атрибутами чтобы быть ограниченным при прямом доступе к модели, вам нужно будет вернуться к использованию attr_accessible
в модели. Что функциональность была перенесена в этот перл: https://github.com/rails/protected_attributes.
Я думаю, предполагается, что если вы работаете с моделью непосредственно в консоли, вам не нужны атрибуты для защиты, поскольку вы точно знаете, что вводится. Поскольку консоль имеет полный доступ к вашему приложению, было бы так же легко поливайте всю базу данных, как это было бы злонамеренно назначить атрибут.
основная причина безопасности для существования обоих сильный параметров и attr_accessible заключается в том, что в модели есть определенные атрибуты, которые не должны быть изменены, если это не явное намерение вашего кода.
небольшая разница между ними-это перспективная форма, в которой они выполняют свою работу.
StrongParameters фокус на случае использования: действие каждого контроллера можно настроить разрешить или запретить определенные параметры, принимая во внимание любое условие. Полная гибкость.
attr_accessible придерживается другой точки зрения. Вместо того, чтобы сосредоточиться на прецеденте, он фокусируется на ролях. Так, например, в зависимости от роли пользователя определенные атрибуты могут быть изменены или нет.
способ использования StrongParameters применить require
и permit
ключевые слова на param хэш.
require
заявляет, что ключ должен присутствовать в хэше params. require
вызовет исключение, если такого ключа нет.
permit
указывает, что поле разрешено. Любой ключ, который не разрешен, будет удален из хэша и, следовательно, не будет передан модели посредством массового назначения.
модель
class League
attr_protected :final_price # Nobody can mass-assign the final price
attr_accessible :winner_name, :as => :jury
end
и контролером
class LeaguesController < ApplicationController
эти два действия использовать StrongParameters
# A common user can create a league
def create
league = League.new(league_params)
league.final_price = 1000
league.save
redirect_to(league)
end
# But only the admin can publish a league
def publish_league
league = League.find(params[:id]
league.update_attributes(league_params_as_admin)
end
этот использует attr_accessible
def publish_the_winner
league = League.find(params[:id]
# We would expect the current_user.role to return :jury.
league.assign_attributes(params[:league], :as => current_user.role)
end
private
def league_params
params.require(:league).permit(:name)
end
def league_params_as_admin
params.require(:league).permit(:name, :status)
end
end
мой опыт:
используйте гибкость сильных параметров, чтобы точно настроить, какие атрибуты могут быть назначены в каждом из ваших контроллеров.
используйте вездесущность attr_accesible, чтобы убедиться, что определенные атрибуты не могут быть массово назначены независимо от того, что. Например, в задаче Resque вы можете передать пользовательский ввод как параметр. Вы бы проверили, что некоторые атрибуты не назначаются массово с помощью attr_accesible.
Подробнее:
http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html
кажется, что белый список активен, даже если вы используете Rails 4. Вы обновились до Rails 4 из приложения Rails 3? У вас есть это в вашем config/application.rb
?
config.active_record.whitelist_attributes = true
дважды проверьте, что сильные параметры действуют на всех ваших моделях. Если они есть, вы можете изменить этот параметр false
.
кроме того, дважды проверьте, что нет attr_accessible
в вашей модели.
Если вы вызываете свои модели напрямую, то да, это обойдет любую логику, которую вы реализовали в своих контроллерах.
однако вы можете вызвать свои контроллеры с консоли, тогда реализованные там StrongParameters вступят в силу.
посмотреть как вызвать методы controller / view из консоли в Rails?