Модули SRP Rails, attr_accessible

Я изучаю SOLID и пытаюсь внедрить SRP в мое приложение rails. У меня есть следующая модель пользователя с базовой аутентификацией:

class User < ActiveRecord::Base
  attr_accessible :password, :password_confirmation
  attr_accessor :password

  before_save :encrypt_password

  validates_confirmation_of :password
  validates_presence_of     :password, :on => :create

  def self.authenticate(email, password)
    user = find_by_email(email)
    if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end

  def self.generate_random_password
    return ActiveSupport::SecureRandom.hex(12)
  end
end

Я хочу переместить всю логику аутентификации в модуль следующим образом:

module Authentication

  attr_accessible :password, :password_confirmation
  attr_accessor :password

  before_save :encrypt_password

  validates_confirmation_of :password
  validates_presence_of     :password, :on => :create

  def self.authenticate(email, password)
    user = find_by_email(email)
    if user && user.password_hash == BCrypt::Engine.hash_secret(password, user.password_salt)
      user
    else
      nil
    end
  end

  def encrypt_password
    if password.present?
      self.password_salt = BCrypt::Engine.generate_salt
      self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
    end
  end

  def self.generate_random_password
    return ActiveSupport::SecureRandom.hex(12)
  end
end

И моя модель пользователя будет выглядеть так:

class User < ActiveRecord::Base
  include Authentication #SRP in action! :P
end

И теперь начинаются ошибки:

неопределенный метод attr_accessible для аутентификации: модуль

Как бы я исправить эту ошибку? Я убежден, что это лучшее начало для представления SRP в моем приложении Rails.

Спасибо

1 ответ

Решение

Метод attr_accessible вызывается в неверной области. Взгляните на проблемы, чтобы исправить это:

http://api.rubyonrails.org/classes/ActiveSupport/Concern.html

Это приведет к:

module Authentication
  extend ActiveSupport::Concern
  included do
    attr_accessible :password, :password_confirmation
  end
  ...
end

Это также позаботится о ваших определениях класса и метода экземпляра.

ПРИМЕЧАНИЕ. Если быть точным, это не совсем обеспечивает SRP, так как несколько обязанностей по-прежнему распределяются внутри одного класса, даже если они разделены на модули. Композиция классов с помощью ссылок или декорирования была бы более строгим решением, но я предпочитаю прагматический подход модулей.

Другие вопросы по тегам