2014-04-28 22 views
3

我已經使用Devise gem向小用戶類添加了一些參數,並且在使用current_password時遇到了一些問題。在我的帳戶更新表單上,當我更新帳戶並輸入當前密碼時,我收到錯誤「不能空白」。該帳戶隨後不會更新。我懷疑它正在被刪除的地方被刪除,然後被讀取爲空白。但我不確定。我在下面列入了我認爲相關的任何內容。使用設計與rails:current_password被消毒?

用戶模型:

class User < ActiveRecord::Base 
    # Include default devise modules. Others available are: 
    # :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :registerable, 
     :recoverable, :rememberable, :trackable, :validatable 

    attr_accessible :username, :email, :password, :password_confirmation, :remember_me, :about_me 

    has_many :microposts 
end 

應用控制器:

class ApplicationController < ActionController::Base 
    protect_from_forgery 

    protected 
    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:username, :email)} 
    devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:username, :email)} 
    devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:username, :about_me, :email, :password, :password_confirmation, :current_password)} 
    end 
end 

密碼控制器:

class Users::PasswordsController < Devise::PasswordsController 

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

註冊控制器

class Users::RegistrationsController < Devise::RegistrationsController 

    before_filter :configure_permitted_parameters 

    protected 

    def configure_permitted_parameters 
    devise_parameter_sanitizer.for(:sign_up) do |u| 
     u.permit(:username, :about_me, :email, :password, :password_confirmation) 
    end 
    devise_parameter_sanitizer.for(:account_update) do |u| 
    u.permit(:username, :about_me, :email, :password, :password_confirmation, :current_password) 
    end 
    end 

end 

路線色器件:

devise_for :users, :controllers => {:registrations => "users/registrations", :passwords => "users/passwords" } 

有問題的視圖(標準色器件/註冊/編輯表格):

<h2>Edit <%= resource_name.to_s.humanize %></h2> 

<%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %> 
    <%= f.error_notification %> 

    <div class="form-inputs"> 
    <%= f.input :email, required: true, autofocus: true %> 
    <%= f.input :username, required: false, autofocus: true %> 
    <%= f.input :about_me, required: false, autofocus: true %> 
    <% if devise_mapping.confirmable? && resource.pending_reconfirmation? %> 
     <p>Currently waiting confirmation for: <%= resource.unconfirmed_email %></p> 
    <% end %> 

    <%= f.input :password, autocomplete: "off", hint: "leave it blank if you don't want to change it", required: false %> 
    <%= f.input :password_confirmation, required: false %> 
    <%= f.input :current_password, hint: "we need your current password to confirm your changes", required: true %> 
    </div> 

    <div class="form-actions"> 
    <%= f.button :submit, "Update" %> 
    </div> 
<% end %> 

<h3>Cancel my account</h3> 

<p>Unhappy? <%= link_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p> 

同樣,問題在於,當所述口令,以確認改變是鍵入字段旁邊會出現錯誤消息「不能爲空」。有任何想法嗎?謝謝

+1

您可以共享提交此表單時生成的服務器日誌。將其添加到問題中。 –

回答

1

這是一個我過去遇到過麻煩的問題,還有一些問題需要解決。默認情況下,Devise的:registerable模塊允許用戶更改其信息,並要求輸入參數:password:password_confirmation。據我瞭解,你試圖要求用戶輸入並確認他們的:current_password

爲了實現您正在尋找的行爲,您必須重寫Devise的RegistrationsController。我也不認爲你需要PasswordsController,因爲Devise的RegistrationsController爲你處理。您需要編寫並實施一種方法,檢查用戶的有效性:current_password,然後通過update操作將它們重定向到正確的位置。您可以在Users::RegistrationController類寫出下面的私有方法:

def needs_password?(user, params) 
    user.email != params[:user][:email] || 
    params[:user][:password].present? || 
    params[:user][:password_confirmation].present? 
end 

然後修改在User::RegistrationsControllerupdate方法如下:

class Users::RegistrationsController < Devise::RegistrationsController 
    def update 
    @user = User.find(current_user.id) 

    successfully_updated = if needs_password?(@user, params) 
     @user.update_with_password(devise_parameter_sanitizer.sanitize(:account_update)) 
    else 
     # remove the virtual current_password attribute 
     # update_without_password doesn't know how to ignore it 
     params[:user].delete(:current_password) 
     @user.update_without_password(devise_parameter_sanitizer.sanitize(:account_update)) 
    end 

    if successfully_updated 
     set_flash_message :notice, :updated 
     # Sign in the user bypassing validation in case their password changed 
     sign_in @user, :bypass => true 
     redirect_to after_update_path_for(@user) 
    else 
     render "edit" 
    end 
    end 

希望這會有所幫助。您也可以參考Devise的文檔瞭解如何操作:https://github.com/plataformatec/devise/wiki/How-To%3a-Allow-users-to-edit-their-account-without-providing-a-password