Rails 4 / Devise / MongoDB:使用自定义属性和强参数的“未允许的参数”

尝试将嵌套的自定义属性Profile (一个Mongoid文档)添加到我的设计用户类。 提交Devise注册表单时,它还应创建用户和相应的Profile对象。

我希望最终结果在我的MongoDB中看起来像这样:

用户:

{ # Devise fields: "email": "my@email.com", ... # 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"=>"my@email.com"}} Unpermitted parameters: profile_attributes 

我有设置:

  • Rails 4.0.0beta1,Ruby 2.0.0-p0
  • 设计(’rails4’分支),Mongoid(来自git)
  • 自定义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" } 

我已经查看了这些相关post,他们似乎没有帮助:

  • Rails 4嵌套属性未允许的参数
  • https://gist.github.com/kazpsp/3350730

编辑:

看起来Devise确实支持其“rails4”分支中的强参数(它应该在几天内合并到master中。)查看代码,看起来你可以为设计控制器上的每个动作覆盖params函数。 对于创建新用户,在我的示例中使用sign_up_params而不是resource_params

尽管将此名称更改为正确的名称仍然无法正常工作…只使用此爆炸将所有参数列入白名单似乎有效:

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

显然,这种方法违背了强参数的目的……所以现在的问题是如何允许我的嵌套属性profile_attributes (如我原来的问题所示)?

我有完全相同的问题,并且压倒sign_up_params确实对我有用

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

当然,不同之处在于我的只是标量值,而你正在尝试大量分配关系……我想这就是你应该寻找的地方。

顺便说一下,这个主题中的文档仍然不存在(太新),并且代码内容建议覆盖devise_parameter_sanitizer ,这是不必要的。

我找到了一种不同的方法,允许所有设计覆盖逻辑和代码驻留在应用程序控制器中 。 这允许为每个设计操作(登录,注册,更新)传递任何和所有自定义参数。 我还为devise_invitable添加了一个参数清理程序,并在此处理该逻辑(invite,accept_invitation)。 我有像头像,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

我在登录时遇到了同样的问题,它说: Unpermitted parameters: password, remember_me 。 因为我有任何inheritanceDevise :: SessionsController的控制器,所以我使用自己的参数sanitizer 。

这是我做的:

在’#{Rails.root} / lib’fold中创建一个文件,我的是hzsapa_parameter_sanitizer.rb并在config / application.rb中需要 ,然后覆盖devise_parameter_sanitizer方法

LIB / 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中找到了解决方案,你可以在这里关注它

我用你的代码,它对我有用!

这就是我做的

 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