Модули 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, так как несколько обязанностей по-прежнему распределяются внутри одного класса, даже если они разделены на модули. Композиция классов с помощью ссылок или декорирования была бы более строгим решением, но я предпочитаю прагматический подход модулей.