Разработать обновление пользователя без пароля - PullRequest
73 голосов
/ 25 февраля 2011

Я хочу обновить атрибуты пользователей без пароля в devise. Дело в том, что если поля пароля и подтверждения пароля не пустые, то мне нужно разработать ошибку, а если они пустые, то другие атрибуты пользователя необходимо обновить. Как я могу сделать это с помощью устройства?

Заранее спасибо!

Ответы [ 14 ]

84 голосов
/ 26 июля 2012

Я думаю, что это гораздо лучшее решение:

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

Это предотвращает необходимость изменения контроллера Devise, просто удаляя поле пароля из ответа формы, если оно пустое.

Обязательно используйте это до @user.attributes = params[:user] или что-либо еще, что вы используете в своем действии update для установки новых параметров из формы.

61 голосов
/ 25 февраля 2011

Это то, что вы ищете?Из вики Devise

Разрешить пользователям редактировать свою учетную запись без ввода пароля

Здесь показано, как это сделать для рельсов 3 и рельсов 4

=======================

Решение Джона является более простой альтернативой

18 голосов
/ 31 января 2014

Я думаю, что с Devise 3.2+ вы можете просто переопределить update_resource в вашем подклассе контроллера. Вот пример для первоначально заданного вопроса:

class MyRegistrationsController < Devise::RegistrationsController
  protected

  def update_resource(resource, params)
    resource.update_without_password(params)
  end
end
7 голосов
/ 14 апреля 2012

Я решил эту проблему следующим образом: если форма отправляется с паролем, то нужно заполнить поле current_password или форму обновлять без пароля и current_password

в модели:

class User
  devise: bla-bla-bla

  attr_accessor :current_password
end

В контроллере:

class Users::RegistrationsController <  Devise::RegistrationsController
  layout 'application'


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


    # custom logic
    if params[:user][:password].present?
      result = resource.update_with_password(params[resource_name])
    else
      result = resource.update_without_password(params[resource_name])
    end

    # standart devise behaviour
    if result
      if is_navigational_format?
        if resource.respond_to?(:pending_reconfirmation?) && resource.pending_reconfirmation?
          flash_key = :update_needs_confirmation
        end
        set_flash_message :notice, flash_key || :updated
      end
      sign_in resource_name, resource, :bypass => true
      respond_with resource, :location => after_update_path_for(resource)
    else
      clean_up_passwords resource
      respond_with resource
    end
  end
end
3 голосов
/ 27 августа 2016

Если вы все еще хотите поддержать изменение пароля, но сделать его необязательным, проверьте наличие current_password следующим образом:

class MyRegistrationsController < Devise::RegistrationsController
  protected

  def update_resource(resource, params)
    if params[:current_password].blank?
     resource.update_without_password(params.except(:current_password))
    else
      resource.update_with_password(params)
    end
  end
end

Таким образом, если присутствует текущий_пароль, вы можете продолжить и обновить пароль,иначе проигнорируй и обнови без пароля.

3 голосов
/ 28 января 2016

Я вместо этого переопределить #password_required?метод внутри модели пользователя.

class User < ActiveRecord::Base
  devise :database_authenticatable, :validatable #, ...

  def password_required?
    if respond_to?(:reset_password_token)
      return true if reset_password_token.present?
    end
    return true if new_record?
    password.present? || password_confirmation.present?
  end
end

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

Подробнее см. https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L33

Моя реализация практически идентична оригинальной: https://github.com/plataformatec/devise/blob/master/lib/devise/models/validatable.rb#L53

за исключением того, что я проверяю наличие (которое возвращает false для пустых строк)

Вот обсуждение моего запроса на получение по этому вопросу: https://github.com/plataformatec/devise/pull/3920

3 голосов
/ 09 февраля 2014

Я решаю эту проблему с помощью моего интерфейса.Это можно сделать двумя способами.

Отключить поля, если они пусты

Этот бит jQuery отключает поля перед отправкой формы в случае, если они пусты.Требуется определенный шаблон разметки, проверьте демонстрацию на Codepen .

$(".password-fields").each(function() {
  var $fields, $form;
  $form = $(this).parents("form");
  $fields = $(this).find("input");
  $form.on("submit", function() {
    $fields.each(function() {
      if ($(this).val() === "") {
        $(this).attr("disabled", "disabled");
      }
    });
  });
});

Дайте пользователю флажок, чтобы выбрать, хотят ли они обновить

Другой вариант -удалите поля пароля из формы, если пользователь не указал, что он хочет обновить свой пароль.Вот пример на CodePen .

$(".password-fields").each(function () {
  var $fields, $button, html;
  $fields = $(this);
  $button = $fields.prev(".update-password").find("input");
  html = $fields.html();

  $button
    .on("change", function () {
      if ( $(this).is(":checked") ) {
        $fields.html(html);
      }
      else {
        $fields.html("");
      }
    })
    .prop("checked", "checked")
    .click();
});

В любом случае не требуется обновление самого приложения.Вы просто отправляете поля, которые хотите изменить.

1 голос
/ 10 июня 2017

В качестве обходного пути, установленного в вашей пользовательской модели

def password_required?
  encrypted_password.blank? || encrypted_password_changed?
end
1 голос
/ 22 октября 2015

Если вы хотите, чтобы Devise проверял текущий пароль только тогда, когда пользователь пытается изменить пароль (, что означает, что вы можете изменить другие атрибуты без предоставления текущего пароля ):

class RegistrationsController < Devise::RegistrationsController

  protected

    def update_resource(resource, params)
      if params[:password].blank? && params[:password_confirmation].blank?
      resource.update_without_password(params)
    else
     super
    end
  end
end

Также в вашей модели:

attr_accessor :current_password

И не забывайте о

devise_for :users, controllers: {registrations: 'registrations'}

в rout.rb .

0 голосов
/ 24 апреля 2019

Лучший и короткий путь: добавьте контрольные параметры в блок user_params. Например:

def user_params
    up = params.require(:user).permit(
      %i[first_name last_name role_id email encrypted_password
         reset_password_token reset_password_sent_at remember_created_at
         password password_confirmation]
    )

    if up[:password].blank? && up[:password_confirmation].blank?
      up.delete(:password)
      up.delete(:password_confirmation)
    end
    up
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...