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?