Rails 4 сильных параметра не работают при создании экземпляров в консоли rails
Наверное, здесь что-то глупо, но здесь мой основной класс резака для печенья:
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
** ОБНОВЛЕНИЕ **
Теперь я понимаю, что сильные параметры применяются теперь в контроллере, а не в модели. Оригинальный вопрос все еще стоит. Если они разрешены на уровне контроллера, как я могу правильно присваивать атрибуты whitelist, если я создаю экземпляры в консоли Rails? Разве мне не нужно было бы использовать attr_accessible
в этом случае и тем самым полностью дублировать то, что сильные параметры пытаются "исправить"?
Ответы
Ответ 1
Две вещи. Определение league_params
относится к контроллеру, а не к модели. И params.require()
должно содержать имя модели, которое должно присутствовать в параметрах, а не атрибутах. Проверка наличия атрибута должна по-прежнему находиться в проверке модели. И убедитесь, что вы действительно хотите разрешить доступ ко всем атрибутам в модели Лиги, прежде чем использовать permit!
. Итак, это должно выглядеть так:
class LeaguesController < ApplicationController
private
def league_params
params.require(:league).permit!
end
end
Update:
Да, если вы хотите, чтобы атрибуты были ограничены при непосредственном доступе к модели, вам нужно будет вернуться к использованию attr_accessible
в модели. Эта функциональность была перенесена в этот драгоценный камень: https://github.com/rails/protected_attributes.
Я думаю, что предполагается, что если вы работаете с моделью непосредственно на консоли, вам не нужны атрибуты, которые нужно защитить, поскольку вы точно знаете, что вводится. Поскольку консоль имеет полный доступ к вашему приложению, было бы так же легко сшить всю базу данных, как и злонамеренно назначать атрибут.
Ответ 2
Основной причиной безопасности существования сильных параметров и attr_accessible является то, что в модели есть определенные атрибуты, которые не должны быть изменены, если только это не явное намерение вашего кода.
Небольшое различие между ними - это перспективная форма, в которой они выполняют свою работу.
StrongParameters сосредоточиться на прецеденте: каждое действие контроллера может быть настроено правильно, чтобы разрешить или запретить определенные параметры, принимая во внимание любое условие. Полная гибкость.
attr_accessible имеет другую перспективу. Вместо того, чтобы сосредоточиться на прецеденте, он фокусируется на ролях. Так, например, в зависимости от роли пользователя некоторые атрибуты могут быть изменены или нет.
Способ использования StrongParameters заключается в применении ключевых слов require
и permit
для хэша param.
require
указывает, что ключ должен присутствовать в хеше params. require
вызовет исключение, если такой ключ отсутствует.
permit
указывает, что поле разрешено. Любой ключ, который не разрешен, будет удален из хэша и, следовательно, не будет передан модели с помощью массового присвоения.
Model
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 Task вы можете передать пользовательский ввод в качестве параметра. Вы должны убедиться, что некоторые атрибуты не назначены по массе, используя attr_accesible.
Дополнительная информация:
http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html
https://github.com/rails/strong_parameters
Ответ 3
Кажется, что белый список активен, даже если вы используете Rails 4. Вы обновили до Rails 4 из приложения Rails 3? У вас есть это в config/application.rb
?
config.active_record.whitelist_attributes = true
Дважды проверьте, что сильные параметры действуют на всех ваших моделях. Если это так, вы можете изменить этот параметр на false
.
Кроме того, дважды проверьте, что в вашей модели нет attr_accessible
.
Ответ 4
Если вы вызываете свои модели напрямую, тогда да, это обойдется любой логикой, которую вы реализовали в своих контроллерах.
Однако вы можете вызывать свои контроллеры с консоли, а затем внедряемые там StrongParameters вступят в силу.
см. Как вызвать методы контроллера/просмотра с консоли в Rails?