7

試圖嵌套自定義屬性,資料(一個Mongoid文件),添加到我的色器件用戶類。當提交設計註冊表時,它應該同時創建一個用戶和相應的配置文件對象。軌道4 /設計/ MongoDB的:「不允許的參數」使用自定義屬性和強參數

我想最終的結果看起來像這樣在我的MongoDB:

用戶:

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

簡介:

{ 
    "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 

我已經安裝:

  • 導軌4.0.0beta1,紅寶石2.0.0-P0
  • 設計( 'rails4' 分支),Mongoid(從GIT)
  • 自定義設計註冊控制器爲強參數添加定義。

模型/ 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" 
       } 

我已經看過這些相關的職位,他們似乎並沒有幫助:


編輯:

看起來設計並實際支持其「rails4」分支強參數(這是應該在幾天內被合併到主。)通過代碼看,你可以覆蓋設計控制器上每個動作的params函數。對於創建新用戶,在我的示例中,它的sign_up_params而不是resource_params

儘管改變這個名字到正確的一個,它仍然沒有工作...只有白名單使用此爆炸的所有參數似乎工作:

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

顯然,這種失敗的強烈目的參數...所以現在的問題是我如何允許我的嵌套屬性profile_attributes(在我的原始問題中看到)?

回答

11

我有相同的問題和壓倒一切的sign_up_params爲我所做的

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

工作,所不同的是在我的只是標量值,而你試圖質量分配關係...我想這就是你應該尋找的地方。

順便說一句,這個主題(太新)的文件仍然不夠,代碼commnents建議覆蓋devise_parameter_sanitizer,這是沒有必要的。

+2

你在哪裏把這個代碼重寫sign_up_params? – 2013-05-12 12:34:00

+0

在從** Devise :: RegistrationsController **繼承的類中,這是你如何覆蓋/擴展它 – 2013-06-12 19:13:45

+3

是的,這是做它的方式...對於哈希(像我的'profile_attributes'),你需要指定每個嵌入式屬性都由設計明確。即:'params.require(:user).permit(:email,:password,:password_confirmation,profile_attributes:[:first_name,:occupation_title])' – 2013-09-07 16:37:07

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 
2

我有同樣的問題,當登錄,它說:Unpermitted parameters: password, remember_me。 因爲我有任何控制器繼承Devise :: SessionsController,所以我用我自己的parameter sanitizer

這裏是我做的:

創建一個文件 '#{} Rails.root/lib目錄' 折,我是hzsapa_parameter_sanitizer.rb的config/application.rb中需要,然後覆蓋devise_parameter_sanitizer方法application_controller.rb

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 

的config/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 

編輯:我剛剛在設計自述文件中找到了解決方案,您c一個跟着它here

4

我發現了一個不同的方法,允許所有的設計重寫邏輯和代碼駐留在應用程序控制器。這允許任何和所有自定義參數通過每個設計動作(登錄,註冊,更新)。我還爲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