Сбой сильных параметров 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

https://github.com/rails/strong_parameters


кажется, что белый список активен, даже если вы используете Rails 4. Вы обновились до Rails 4 из приложения Rails 3? У вас есть это в вашем config/application.rb?

config.active_record.whitelist_attributes = true

дважды проверьте, что сильные параметры действуют на всех ваших моделях. Если они есть, вы можете изменить этот параметр false.

кроме того, дважды проверьте, что нет attr_accessible в вашей модели.


Если вы вызываете свои модели напрямую, то да, это обойдет любую логику, которую вы реализовали в своих контроллерах.

однако вы можете вызвать свои контроллеры с консоли, тогда реализованные там StrongParameters вступят в силу.

посмотреть как вызвать методы controller / view из консоли в Rails?