2011-02-05 9 views
6

今私はこのトピックが以前何度もカバーされていることを認識しています。しかし、データベース内のパスワードが空白の場合にのみ現在のパスワードフィールドを除外するソリューションがあるようには見えませんでした。Ruby on Rails、Devise gem。パスワードが空白のときに現在のパスワードを削除する方法は?

私は、現在のように私のユーザモデルに必要なパスワードがあります。

def password_required? 
    (authentications.empty? || !password.blank?) && super 
end 

をそれから私は私の登録コントローラに渡って更新機能をコピー:

def update 
    if resource.update_with_password(params[resource_name]) 
    set_flash_message :notice, :updated 
    sign_in resource_name, resource, :bypass => true 
    redirect_to after_update_path_for(resource) 
    else 
    clean_up_passwords(resource) 
    render_with_scope :edit 
    end 
end 

私はどのようにするのか分かりません空白のパスワードを編集するときにパスワードを必要としないようにするには、ビューからcurrent_passwordフィールドを削除して、これを行う必要がありますか?

<% if current_user.password_required? %> 
    <p><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br /> 
    <%= f.password_field :current_password %></p> 
<% end %> 
<p><%= f.submit "Update" %></p> 

私は何かを見落としていると確信しているので、どんな提案も素晴らしいですが、私はまだレール全体に新しいです。ありがとう!

答えて

8

私はついにこのことを理解しました。

あなたのクラスRegistrationsController <工夫に以下を追加します:: RegistrationsController

def update 
    if resource.update_with_password(params[resource_name]) 
    set_flash_message :notice, :updated 
    sign_in resource_name, resource, :bypass => true 
    redirect_to after_update_path_for(resource) 
    else 
    clean_up_passwords(resource) 
    render_with_scope :edit 
    end 
end 

を次に、あなたのUserモデルに次の:私はおよそ少し混乱していた

def update_with_password(params={}) 
    current_password = params.delete(:current_password) if !params[:current_password].blank? 

    if params[:password].blank? 
    params.delete(:password) 
    params.delete(:password_confirmation) if params[:password_confirmation].blank? 
    end 

    result = if has_no_password? || valid_password?(current_password) 
    update_attributes(params) 
    else 
    self.errors.add(:current_password, current_password.blank? ? :blank : :invalid) 
    self.attributes = params 
    false 
    end 

    clean_up_passwords 
    result 
end 

def has_no_password? 
    self.encrypted_password.blank? 
end 

唯一のものがでていることです編集ビュー:

<% if !current_user.has_no_password? %> 

私はそれがされているだろうと思っているだろう、場合、私はそれに包み:誰もが私のコードか、私に知らせて異なる、より効率的な方法を改善するために何を見ることができます

<% if current_user.has_no_password? %> 

場合は!

+1

'current_user.has_no_passwordが' 'true'をを返します。そうでなければ、私は、現在のパスワードのparamをクリアして、(この方法は、今にも工夫することで構築されています)update_without_passwordを呼び出します? if文はそのブロックを実行します。あなたは、その文を検証するために否定的な言葉を使っています...あなたが 'current_user.has_no_password? 'を書いてはいけないのですが、まだ面白いと読んでください。 'current_user.has_password?'を実行し、 'self.encrypted_pa​​ssword.present?'を返すように定義すると読みやすくなります(これについては後述しますが、これはコメントに含まれています。 、もっと読みやすい解決策) – wulftone

+0

私はこれを他の何かの基礎として使っていました。変更のみ:現在のパスワードが '' ''に設定されていたので、大量割り当てエラーを避けるために 'if!params [:current_password] .blank? 'を削除しなければならなかった(したがって' 'blank?== true')しかし、 'update_attributes(params)'は ':current_password => '''でユーザレコードを更新しようとしました。 'current_password'はユーザの属性ではないので、明らかに失敗します。私はスティックの間違った終わりを持っている?また、 '自己'は冗長ではない? – dgmstuart

+0

私はこの解決策を試しました。保護属性を大量に割り当てることはできません:current_password – simo

3

現在のパスワードフィールドを要求しているかどうかについて、非常にマイナーな変更があります。パスワードを更新していない限り、現在のパスワードは決して必要ありません。 oauth'edアカウントの場合は、ビューのfacebook idを確認し、パスワードフィールドはまったく表示しません。登録コントローラで

:User.rbで

Users::RegistrationsController < Devise::RegistrationsController 

def update 

self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key) 

    if resource.update_with_password(params[resource_name]) 
    set_flash_message :notice, :updated if is_navigational_format? 
    sign_in resource_name, resource, :bypass => true 
    respond_with resource, :location => after_update_path_for(resource) 
    else 
    clean_up_passwords(resource) 
    respond_with_navigational(resource){ render_with_scope :edit } 
    end 


end 

、私はupdate_with_password使用して、ユーザーがビューからパスワードフィールドに何かを入力した場合にのみverify_password_and_update呼び出します。このように、パスワードがない場合

#to remove the current password check if updating a profile originally gotten via oauth (fb, twitter) 


    def update_with_password(params={}) 
    if params[:password].blank? 
     params.delete(:current_password) 
     self.update_without_password(params) 
    else 
     self.verify_password_and_update(params) 
    end 
    end 

    def update_without_password(params={}) 

    params.delete(:password) 
    params.delete(:password_confirmation) 
    result = update_attributes(params) 
    clean_up_passwords 
    result 
    end 
    def verify_password_and_update(params) 
    #devises' update_with_password 
    # https://github.com/plataformatec/devise/blob/master/lib/devise/models/database_authenticatable.rb 
    current_password = params.delete(:current_password) 

    if params[:password].blank? 
     params.delete(:password) 
     params.delete(:password_confirmation) if params[:password_confirmation].blank? 
    end 

    result = if valid_password?(current_password) 
     update_attributes(params) 
    else 
     self.attributes = params 
     self.valid? 
     self.errors.add(:current_password, current_password.blank? ? :blank : :invalid) 
     false 
    end 

    clean_up_passwords 
    result 
    end 
+0

あなたのコードを共有してくれてありがとう。私はしばらくの間これをやっていて、あなたのコードが助けられているのを見た=) – Sasha

+0

問題なし、それは助けてくれてうれしい! – Danny

関連する問題