Вопрос по strong-parameters, devise, ruby-on-rails-4, mongodb, ruby-on-rails – Rails 4 / Devise / MongoDB: «недопустимые параметры» с использованием пользовательских свойств и сильных параметров

7

Пытаясь добавить вложенный пользовательский атрибут,Профиль (Mongoid документ), к моему устройствупользователь учебный класс. Когда форма регистрации Devise представлена, она должна создатьпользователь и соответствующийПрофиль объект также. Я '

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

Пользователь:

{
  # Devise fields:
  "email": "[email protected]",
  ...
  # Custom field
  "profile" : ""
}

Профиль:

{
  "first_name": "Dave",
  ....
}

К сожалению, я получаю это в своей консоли всякий раз, когда я отправляю свою регистрацию. Он успешно создает пользователя, но не может создать связанный профиль.

Started POST "/" for 127.0.0.1 at 2013-04-20 23:37:10 -0400
Processing by Users::RegistrationsController#create as HTML
Parameters:
   {"utf8"=>"✓",
   "authenticity_token"=>"awN2GU8EYEfisU0",
   "user"=>
       {"profile_attributes"=>
           {"first_name"=>"Dave",
           "birthday(2i)"=>"4",
           "birthday(3i)"=>"21",
           "birthday(1i)"=>"1933",
           "occupation_title"=>"Software Developer"},
        "password"=>"[FILTERED]",
        "password_confirmation"=>"[FILTERED]",
        "email"=>"[email protected]"}}
Unpermitted parameters: profile_attributes

У меня есть настройки:

Rails 4.0.0beta1, Ruby 2.0.0-p0Придуматьrails4' ветка), монгоид (из мерзавца)Пользовательский контроллер регистрации Devise для добавления определения сильных параметров.

модели / user.rb:

class User
  include Mongoid::Document

  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable,
     :token_authenticatable, :confirmable, :lockable, :timeoutable

  field :email,              type: String, default: ''

  ...

  has_one :profile
  accepts_nested_attributes_for :profile
end

модели / profile.rb:

class Profile
  include Mongoid::Document
  include Mongoid::Timestamps

  # Attributes
  # ----------
  field :slug,                type: String, default: '' # Acts as user-'friendlier' slug
  field :birthday,            type: DateTime, default: DateTime.now
  field :first_name,          type: String, default: ''
  field :occupation_title,    type: String, default: ''

  belongs_to :user
  embeds_many :photos
  has_one :occupation_industry, :as => :industry
end

Контроллеры / пользователи / registrations_controller.rb

class Users::RegistrationsController < Devise::RegistrationsController

  def resource_params
    params.require(:user).permit(:email, :password, :password_confirmation, :profile_attributes)
  end
  private :resource_params
end

routes.rb

devise_for  :users,
              :path => '',
              :path_names => {
                :sign_in => 'login',
                :sign_out => 'logout',
                :sign_up => 'register'
                },
              :controllers => {
                :registrations => "users/registrations",
                :passwords => "users/passwords"
              }

Я уже посмотрел на эти посты, они некажется, чтобы помочь:

Вложенные атрибуты Rails 4: недопустимые параметрыhttps://gist.github.com/kazpsp/3350730

РЕДАКТИРОВАТЬ:

Похоже, Devise действительно поддерживает сильные параметры в своихrails4' ветвь (которая должна быть объединена с мастером через несколько дней.) Просматривая код, вы можете переопределить функцию params для каждого действия на контроллерах devise. Для создания новых пользователей, егоsign_up_params вместоresource_params в моем примере.

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

def sign_up_params
  params.require(:user).permit!
end

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

Ваш Ответ

4   ответа
2

Unpermitted parameters: password, remember_me, и потому, что у меня есть любой контроллер, который наследуетРазрабатывают :: SessionsControllerтак что я использую свой собственныйдезинфицирующее средство

вот что я делаю:

Создать файл в '# {Rails.root} / Библиотека» сложитеhzsapa_parameter_sanitizer.rb и требуется вконфиг / application.rbзатем переопределитьdevise_parameter_sanitizer метод вapplication_controller.rb

Библиотека / hzsapa_parameter_sanitizer.rb

class HzsapaParameterSanitizer < Devise::ParameterSanitizer
  def sign_in
    default_params.permit(auth_keys + [:password, :remember_me])
  end
end

Вы можете переопределить этот метод в зависимости от вашей проблемы:

def sign_in
  default_params.permit(auth_keys)
end

def sign_up
  default_params.permit(auth_keys + [:password, :password_confirmation])
end

def account_update
  default_params.permit(auth_keys + [:password, :password_confirmation,    :current_password])
end

конфиг / application.rb

require "hzsapa_parameter_sanitizer"

Приложение / application_controller.rb

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception

  def devise_parameter_sanitizer
    @devise_parameter_sanitizer ||= if defined?(ActionController::StrongParameters)
                                      HzsapaParameterSanitizer.new(resource_class, resource_name, params)
                                    else
                                      Devise::BaseSanitizer.new(resource_class, resource_name, params)
                                    end
  end
end

Редактировать: Я только что нашел решение в README, вы можете следить за нимВот

1

Вот что я сделал

class RegistrationsController < Devise::RegistrationsController
  skip_before_filter :verify_authenticity_token, :only => :create #, :if => Proc.new { |c| c.request.format == 'application/json' }
  respond_to :json, :html, :xml

  def create
    user = User.new(devise_registrations_permitted_parameters)
    if user.save
      render :json=> user.as_json(:auth_token=>user.authentication_token, :email=>user.email,:name => user.name), :status=>201
      return
    else
      warden.custom_failure!
      render :json=> user.errors, :status=>422
    end
  end


  protected                                                            
    def devise_registrations_permitted_parameters
      params.require(:user).permit(:name, :email, :password, :password_confirmation)
    end

end
11

У меня была точно такая же проблема и переопределениеsign_up_params работал на меня

def sign_up_params
   params.require(:user).permit(:email, :password, :password_confirmation, :other, :etc)
end

конечно, разница в том, что мои - это просто скалярные значения, а выпытаюсь массово назначить отношение ...где вы должны искать.

Кстати, документация в этой теме еще не истекла (слишком новая), и компоненты кода предлагают переопределитьdevise_parameter_sanitizerкоторый нет необходимо.

Где вы размещаете этот код для переопределения sign_up_params? Steve Grossi
В классе, наследующем отРазрабатывают :: RegistrationsControllerэто то, как вы переопределяете / расширяете его comandante N
Да, это способ сделать это ... для хэшей (как мойprofile_attributes), вам необходимо явно указать каждый встроенный атрибут. то есть это выглядит примерно так:params.require(:user).permit(:email, :password, :password_confirmation, profile_attributes: [:first_name, :occupation_title]) David Elner
4

Я нашел другой метод, который позволяетвся логика и код переопределения устройства находятся в контроллере приложения, Это позволяет передавать любые пользовательские параметры для каждого действия устройства (вход, регистрация, обновление). Я также добавляю параметр sanitizer для devise_invitable и обрабатываю эту логику здесь (инвайт, accept_invitation). Я'у нас есть пользовательские параметры, такие как avatar, avatar_cache и т.д .:

#application_controller.rb

  before_filter :configure_permitted_parameters, if: :devise_controller?

protected
  # There are just three actions in Devise that allows any set of parameters to be passed down to the model, 
  # therefore requiring sanitization. Their names and the permited parameters by default are:

  # sign_in (Devise::SessionsController#new) - Permits only the authentication keys (like email)
  # sign_up (Devise::RegistrationsController#create) - Permits authentication keys plus password and password_confirmation
  # account_update (Devise::RegistrationsController#update) - Permits authentication keys plus password, password_confirmation 
  # and current_password. More at https://github.com/plataformatec/devise#strong-parameters

  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:accept_invitation) do |u|
      u.permit(:username,:validate_username, :password,:password_confirmation, :invitation_token)
    end
    devise_parameter_sanitizer.for(:invite) do |u|
      u.permit(:name,:comments)
    end

    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:username,:password,:password_confirmation)
    end
    devise_parameter_sanitizer.for(:sign_in) do |u|
      u.permit(:username,:email,:password,:password_confirmation,:phone, :validate_username, :avatar_cache, :remove_avatar, :current_password,:remember_me)
    end

    devise_parameter_sanitizer.for(:account_update) do |u|
      u.permit(:username,:email,:password,:password_confirmation,:phone, :validate_username,:avatar, :avatar_cache, :remove_avatar, :current_password)
    end
  end

Найти и прочитать больше наhttps://github.com/plataformatec/devise#strong-parameters

Похожие вопросы