Rails 中的 ActiveModel 如何通过在模型中添加单行 "has_secure_password" 来向模型 class 添加方法?

How ActiveModel in Rails add methods to model class by just having single line "has_secure_password" in model?

在 Rails (4.2.6) 中,我可以在 Gemfile 中包含 gem 'bcrypt',安装它,然后在我的模型 [=30] 中简单地添加行 'has_secure_password' =].

我想知道它是如何向我的模型添加方法的 class。

如果我正在 github - https://github.com/rails/rails/blob/52ce6ece8c8f74064bb64e0a0b1ddd83092718e1/activemodel/lib/active_model/secure_password.rb 上查看 SecurePassword 的来源 我看到以下几行

module ActiveModel
  module SecurePassword
    extend ActiveSupport::Concern
      module ClassMethods
        def has_secure_password(options = {})
        ...
          include InstanceMethodsOnActivation
        ...
        end
      ..

module InstanceMethodsOnActivation
  def authenticate(unencrypted_password)
....

include 调用如何在方法内部工作?它如何将实例方法添加到我的模型 class?我的模型中的 ClassMethods 模块 "gets" 怎么样?

不知何故 "extending" 我的 class 因为我使用了 has_secure_password 电话?或者如果打开相应的gem它默认扩展每个模型?

了解任何事物正在做什么的最简单方法是!在这种情况下,那将是文档 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
  • 方法内部的 include 调用如何工作?

所有 ActiveRecord::Base class 都有一个 class 方法 :has_secure_password

$ rails console
=> ActiveRecord::Base.respond_to? :has_secure_password
=> true
  • 它如何向我的模型添加实例方法class?
  • 我的模型中的 ClassMethods 模块 "gets" 怎么样?

ActiveSupport::Concern魔法.

  • 不知何故 "extending" 我的 class 因为我用过 has_secure_password 打电话?

没有

  • 或者如果相应的gem是默认扩展每个模型 开启了吗?

不,它只是默认扩展您的模型。