我目前正在研究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>
可以访问其中的每个方法。那么定义这样的方法不是多余或错误的吗?
答案 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")