Ruby on Rails, разработайте самоцвет.Как удалить текущий пароль, если пароль пуст? - PullRequest
6 голосов
/ 05 февраля 2011

Теперь я понимаю, что эта тема уже освещалась много раз.Однако, похоже, что не существует решения, которое хотело бы освободить поле текущего пароля только тогда, когда пароль в базе данных был пустым.

В настоящее время у меня есть пароль, требуемый в моей модели пользователя, такой как:

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

Я просто не знаю, как добиться того, чтобы devise не нуждался в пароле при редактировании пустого пароля,мне также нужно удалить поле 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>

Любые предложения были бы хорошими в этом, так как я уверен, что что-то пропускаю, но я все еще новичок в Rails в целом,Спасибо!

Ответы [ 2 ]

8 голосов
/ 05 февраля 2011

Хорошо, так что я наконец-то понял это!

Добавьте следующее в ваш класс 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

Затем следующее для вашей модели пользователя:

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

Если кто-нибудь может увидеть что-то, что улучшит мой код, или другим, более эффективным способом, дайте мне знать!

3 голосов
/ 03 сентября 2011

Еще одно очень незначительное изменение, требующее или нет текущего поля пароля: моя цель - никогда не требовать текущий пароль, если они не обновляют свой пароль. для учетных записей oauth'а я проверяю идентификатор Facebook в представлении и вообще не отображаю поля пароля.

В контроллере регистрации:

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

В User.rb я использую update_with_password, а затем вызываю verify_password_and_update, только если пользователь ввел что-то в поле пароля из представления. В противном случае я очищаю текущий параметр пароля и вызываю update_without_password (этот метод также встроен для разработки сейчас):

#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
...