Разработайте удаление пользователя, но сохраните его данные и установите флаг _is_deleted в rails 3.1 - PullRequest
2 голосов
/ 07 декабря 2011

Я хотел бы удалить пользователя с помощью devise, но иметь возможность сохранить его данные, просто установив флаг, подобный is_deleted, в значение true и запретив вход для этих пользователей.

Каков наилучший способ сделать это в разработке? Я видел несколько статей по этому вопросу, но они были для проектов rails 2.x, я на rails 3.1

Ответы [ 4 ]

5 голосов
/ 17 июня 2012

Если вы хотите запретить вход в систему пользователям, чьи поля selected_at не равны NULL, переопределите active_for_authentication? в модели ресурсов вашего устройства:

def active_for_authentication?
  super && !deleted_at
end
4 голосов
/ 08 декабря 2011

Вы можете установить этот удаленный флаг как обычно, а затем переопределить метод уровня класса find_for_authentication в модели пользователя.

Следующее должно работать

def self.find_for_authentication(conditions) 
  super(conditions.merge(:is_deleted => false))
end
1 голос
/ 10 апреля 2012

Другой подход заключается в использовании области действия по умолчанию для вашей модели.Определите состояние для вашей модели User и добавьте область по умолчанию (Rails 3), это будет охватывать все запросы в модели User с условием из области:

app / models / user.rb

class User < ActiveRecord::Base

  default_scope where("state  != 'disabled'")

  def disable!
    self.update_attribute(:state, 'disabled')
  end

end

Затем переписать метод destroy в контроллере сеанса, убедитесь, что вы получили код уничтожения из используемой вами версии устройства:

* app / controllers / registrations_controller.rb *

class Users::RegistrationsController < Devise::RegistrationsController

  # paranoid DELETE /resource
  def destroy
    resource.disable! # we don't remove the record with resource.destroy
    Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
    set_flash_message :notice, :destroyed if is_navigational_format?
    respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
  end

end

Вы можете сделать еще один шаг, определив конечный автомат в своей модели пользователя (будьте осторожны, чтобы не каскадироватьдерево зависимостей, как :dependent => :destroy):

app / models / user.rb

class User < ActiveRecord::Base
include ActiveRecord::Transitions

  state_machine do
    state :passive
    state :active
    state :disabled, :enter => :bye_bye_user

    event :activate do
      transitions :from => :passive, :to => :active
    end
    event :disable do
      transitions :from => [:passive,:active], :to => :disabled
    end
  end

  default_scope where("state  != 'disabled'")

end
0 голосов
/ 10 мая 2013

@ dgmdan: в отношении использования: dele_at => nil вместо false:

Метод Devise find_for_authentication пропускает условия через фильтр , который преобразует значения . Происходит то, что значение nil, передаваемое для deleted_at, преобразуется в пустую строку. Это делает запрос не соответствующим никому, и, таким образом, конечному пользователю кажется, что имя пользователя и пароль были неверными.

find_for_authentication звонки find_first_by_auth_conditions вот так:

def find_for_authentication(tainted_conditions)
  find_first_by_auth_conditions(tainted_conditions)
end

Согласно автору , find_first_by_auth_conditions принимает необязательный второй параметр, другой хэш условий, но этот не проходит через фильтр. Итак, вы можете изменить метод следующим образом:

def self.find_for_authentication(conditions)
  find_first_by_auth_conditions(conditions, {:deleted_at => nil})
end

Второй хэш условий с :deleted_at => nil должен быть передан прямо в слой ORM.

...