Rails 4 сильных параметра не работает при создании экземпляров в консоли rails

Возможно, здесь вы делаете что-то глупое, но вот мой базовый класс резака для печенья:

class League < ActiveRecord::Base

    private
      def league_params
        params.require(:full_name).permit!
      end

end

И при создании нового экземпляра League:

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 + Ruby 2.0

** ОБНОВИТЬ **

Теперь я понимаю, что строгие параметры теперь применяются в контроллере, а не в модели. Первоначальный вопрос все еще остается в силе. Если они разрешены на уровне контроллера, как я могу правильно занести атрибуты в белый список, если я создаю экземпляры в консоли Rails? Разве мне не нужно было бы также использовать attr_accessible в этом случае, тем самым полностью дублируя те сильные параметры, которые пытается «исправить»?


person randombits    schedule 11.04.2013    source источник
comment
Вы можете опубликовать свой Gemfile? Также код в вашей модели?   -  person Agis    schedule 14.04.2013
comment
@randombits вы обновили свой проект с rails3?   -  person AKovtunov    schedule 07.07.2013


Ответы (4)


Две вещи. Определение 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.

Я думаю, предполагается, что если вы работаете с моделью непосредственно в консоли, вам не нужно защищать атрибуты, поскольку вы точно знаете, что вводится. Поскольку консоль имеет полный доступ к вашему приложению, было бы так же легко промыть всю базу данных, как злонамеренно присвоить атрибут.

person ericeason    schedule 11.04.2013
comment
Что делать, если Лига не создается в контроллере? В данном случае я создаю его в консоли. - person randombits; 13.04.2013
comment
Тогда вам не нужно использовать разрешенные параметры. Разрешенные параметры используются для защиты от данных, введенных пользователем. - person spullen; 13.04.2013
comment
так что мне все равно нужно вернуться к attr_accessible? - person randombits; 13.04.2013

Основная причина безопасности существования как строгих параметров, так и attr_accessible заключается в том, что в модели есть определенные атрибуты, которые нельзя изменять, если только это не явное намерение. вашего кода.

Небольшая разница между ними заключается в том, в какой перспективе они выполняют свою работу.

StrongParameters ориентирован на вариант использования: каждое действие контроллера можно настроить, чтобы разрешить или запретить определенные параметры с учетом любых условий. Полная гибкость.

attr_accessible придерживается другой точки зрения. Вместо того, чтобы сосредотачиваться на варианте использования, он сосредотачивается на ролях. Так, например, в зависимости от роли пользователя определенные атрибуты могут быть изменены или нет.


Способ использования StrongParameters заключается в применении ключевых слов require и permit к хешу параметров.

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, чтобы убедиться, что определенные атрибуты не могут быть назначены массово, несмотря ни на что. Например, в задаче восстановления вы можете передать ввод пользователя в качестве параметра. Вы можете проверить, что некоторые атрибуты не назначаются массово, используя attr_accesible.

Больше информации:

http://api.rubyonrails.org/classes/ActiveModel/MassAssignmentSecurity/ClassMethods.html

https://github.com/rails/strong_parameters

person Nerian    schedule 14.04.2013

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

config.active_record.whitelist_attributes = true

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

Кроме того, еще раз проверьте, что в вашей модели нет attr_accessible.

person clacke    schedule 19.04.2013
comment
Я не автор темы, но спасибо. Когда я обновил свой проект с Rails3 до Rails4, было показано это сообщение. Но если я создам проект Rails 4 с тем же кодом (даже в конфигах), сообщение не будет отображаться. Не знаю почему, это похоже на небольшую ошибку. - person AKovtunov; 07.07.2013
comment
Невозможно обновить это прозрачно, требуется помощь разработчика. Я считаю, что на исходном плакате должен был быть добавлен драгоценный камень protected_attributes, иначе произошла бы ошибка. (Возможно, ошибка подсказывает вам установить этот драгоценный камень, у меня нет нужного компьютера для проверки). Лучший способ перейти на Rails 4 - сначала использовать гем strong_parameters и пройти через все контроллеры и модели, чтобы они работали по-новому, только после этого обновите гем Rails. - person clacke; 09.07.2013
comment
Конфигурация вашего проекта Rails 4 действительно такая же? Я предполагаю, что указанная строка конфигурации отсутствует или имеет значение false. - person clacke; 21.08.2013

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

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

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

person Nigel Thorne    schedule 15.04.2013