Как работает has_secure_password в моем классе модели?

Я делаю Rails учебник Майкла Хартла, и я пришел к тому, что вы просто добавили:

has_secure_password

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

Я понимаю, что этот метод исходит из модуля ActiveModel::SecurePassword, который включен в ActiveRecord::Base, который расширяется мой класс модели.

Я не понимаю, что происходит, когда я добавляю эту строку в определение класса. Может кто-нибудь, пожалуйста, объясните, насколько это возможно. Я действительно хочу понять, что происходит, а не просто бросать вещи в мое приложение, не зная, как это работает.

(Если это помогает понять, почему я запутался, я пришел из фона Java, и я новичок в Ruby)

Ответ 1

Самый простой способ понять, что делать, - это обратиться к источнику! В этом случае это будет ActiveModel:: Документация SecurePassword. Из этого вы можете видеть, что has_secure_password делает это:

def has_secure_password
  # Load bcrypt-ruby only when has_secure_password is used.
  # This is to avoid ActiveModel (and by extension the entire framework) being dependent on a binary library.
  gem 'bcrypt-ruby', '~> 3.0.0'
  require 'bcrypt'

  attr_reader :password

  validates_confirmation_of :password
  validates_presence_of     :password_digest

  include InstanceMethodsOnActivation

  if respond_to?(:attributes_protected_by_default)
    def self.attributes_protected_by_default
      super + ['password_digest']
    end
  end
end

Чтобы объяснить на английском языке эту функцию:

  • Загружает bcrypt-ruby Gem и требует bcrypt. bcrypt - это безопасная хеширующая функция, о которой вы можете узнать больше в Википедии.
  • Добавляет атрибут только для чтения к модели под названием password.
  • Проверяет, что пароль подтвержден другим полем, называемым password_confirmation. Другими словами, вы должны ввести пароль дважды, чтобы подтвердить его.
  • Обеспечивает, что password_digest присутствует до сохранения модели.
  • Загрузите методы экземпляра, которые в этом случае authenticate (который возвращает true, если пароль верен, в противном случае - false) и password=, который шифрует переданный пароль в атрибут password_digest.
  • Если у метода есть атрибуты, которые по умолчанию защищены, это также добавит password_digest к этому списку защищенных атрибутов. (Таким образом, предотвращение его назначения массой.) ​​

Вы можете узнать больше в ActiveModel:: Документация SecurePassword и дальнейшая документация по атрибутам экземпляра.