Railstutorial.org第8章:摘要方法定义

时间:2015-07-29 09:55:17

标签: ruby-on-rails ruby railstutorial.org

我目前正在研究Michael Hartl的Rails教程,我发现了一个方法定义我不太了解:

class User < ActiveRecord::Base


before_save { self.email = email.downcase }
  validates :name,  presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, length: { maximum: 255 },
                    format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
  has_secure_password
  validates :password, presence: true, length: { minimum: 6 }

  # Returns the hash digest of the given string.
  def User.digest(string)
    cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST :
                                                  BCrypt::Engine.cost
    BCrypt::Password.create(string, cost: cost)
  end
end

关键部分是User.digest的定义......他为什么写def User.digest(string)而不只是def digest(string) ......

我们在User类中,因此User.<method_name>可以访问其中的每个方法。那么定义这样的方法不是多余或错误的吗?

2 个答案:

答案 0 :(得分:3)

如果您执行def digest(string),则实际上是在定义实例方法。

在此处阅读有关类和实例方法的更多信息:http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/

Michael Hartl实际上解释了为什么他在底部以这种方式定义了 class 方法(第8.6节第1点)。

  

...我们通过使用User明确地为它们添加前缀来定义新的令牌和摘要类方法。这很好用,因为它们实际上是使用User.new_token和User.digest调用的,所以它可能是定义它们的最清晰的方法....

定义User类方法的其他选择是:

def self.digest(string)
  #your code here
end

class << self
  def digest(string)
    #your code here
  end
end

希望这有帮助!我也用他的书学习了Rails:)

答案 1 :(得分:1)

以下是类方法,它们彼此相同:

def User.digest(string)
  # MY LOGIC
end

def self.digest(string)
  # MY LOGIC
end

类方法直接在类User.digest("my_string")上调用。

  

我们在User类中,因此用户可以访问其中的每个方法。

不幸的是,这是 NOT true。只使用User.<method_name>调用类方法。

如果您已定义方法

def digest(string)
  # MY LOGIC
end

上面是实例方法,将在User类的实例(对象)上调用(不直接在类上),如:

user = User.new
user.digest("string")