2011-02-05 41 views
6

Bây giờ tôi nhận ra chủ đề này đã được đề cập nhiều lần trước đây. Tuy nhiên, dường như không có giải pháp nào muốn làm cho trường mật khẩu hiện tại chỉ được miễn khi mật khẩu trong cơ sở dữ liệu trống.Ruby on Rails, Devise đá quý. Làm cách nào để xóa mật khẩu hiện tại khi mật khẩu trống?

Tôi hiện đã mật khẩu cần thiết trong mô hình người dùng của tôi như:

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

Sau đó, tôi sao chép chức năng cập nhật qua vào đăng ký điều khiển của tôi:

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 

Tôi chỉ không biết làm thế nào để đi về đảm bảo rằng devise không cần một mật khẩu khi chỉnh sửa một mật khẩu trống, tôi cũng cần phải loại bỏ trường current_password từ xem và làm điều này?

<% 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> 

Bất kỳ đề xuất nào đều tuyệt vời về điều này vì tôi chắc chắn tôi đang xem một số thứ nhưng tôi vẫn còn mới đối với Rails. Cảm ơn!

Trả lời

8

Được rồi vì vậy tôi cuối cùng cũng đã tìm ra điều này!

Thêm dòng sau vào RegistrationsController lớp học của bạn < lập mưu :: 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 

Rồi sau để mô hình tài khoản của bạn:

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 

Điều duy nhất tôi đã hơi nhầm lẫn về là trong chỉnh sửa chế độ xem:

<% if !current_user.has_no_password? %> 

Tôi quấn nó ở chỗ nếu, tôi đã có thể nghĩ nó đã có:

<% if current_user.has_no_password? %> 

Nếu bất cứ ai có thể nhìn thấy bất cứ điều gì để cải thiện mã của tôi hoặc một cách hiệu quả hơn khác nhau cho tôi biết!

+1

'current_user.has_no_password' trả về 'true' nếu không có một mật khẩu, do đó nếu câu lệnh thực thi khối của nó. Bạn đang sử dụng ngôn ngữ tiêu cực để xác nhận câu lệnh đó ... bạn nên viết 'trừ khi current_user.has_no_password?', Nhưng nó vẫn đọc vui. Nó dễ đọc hơn nếu bạn làm 'current_user.has_password?' Và đặt định nghĩa trả về 'self.encrypted_password.present?' (Tôi nhận ra điều này đã được thảo luận dưới đây, nhưng điều này thuộc về các chú thích, và tôi đã đưa ra một thay thế giải pháp dễ đọc hơn) – wulftone

+0

Tôi đã sử dụng nó làm cơ sở cho một thứ khác và nó hoạt động khá nhiều.Chỉ thay đổi: Tôi phải xóa 'if! Params [: current_password] .blank?' Để tránh nhận các lỗi gán hàng loạt, vì mật khẩu hiện tại đã được đặt thành '" "' (và do đó 'trống? == true') do đó không bị xóa khỏi các tham số, và sau đó 'update_attributes (params)' đã cố cập nhật bản ghi người dùng bằng ': current_password =>" '' - rõ ràng là không thành công vì 'current_password' không phải là thuộc tính trên người dùng ... Tôi đã có kết thúc sai của thanh mặc dù? Ngoài ra không phải là 'tự' s dự phòng? – dgmstuart

+0

Tôi đã thử giải pháp này, tôi đã nhận Không thể gán hàng loạt thuộc tính được bảo vệ: current_password – simo

3

Một thay đổi nhỏ khác về yêu cầu trường mật khẩu hiện tại hay không: mục tiêu của tôi không bao giờ yêu cầu mật khẩu hiện tại trừ khi họ đang cập nhật mật khẩu của họ. cho tài khoản oauth'ed, tôi kiểm tra id facebook trong chế độ xem và không hiển thị trường mật khẩu.

Trong bộ điều khiển đăng ký:

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 

Trong User.rb, tôi sử dụng update_with_password, và sau đó gọi verify_password_and_update chỉ khi người dùng đã nhập một cái gì đó trong lĩnh vực mật khẩu từ màn hình. Nếu không, tôi xóa param mật khẩu hiện tại và gọi update_without_password (phương pháp này được xây dựng trong để đưa ra bây giờ là tốt):

#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

cảm ơn bạn rất nhiều vì đã chia sẻ mã của bạn. tôi đã bị mắc kẹt làm điều này trong một thời gian và nhìn thấy mã của bạn đã giúp =) – Sasha

+0

không có vấn đề, vui mừng nó đã giúp! – Danny

Các vấn đề liên quan