Railstutorial.org 第8章:摘要方法定义
Railstutorial.org Chapter 8: digest method definition
我目前正在学习 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)
...
我们在用户 class 中,因此 User.<method_name>
应该可以访问其中的每个方法。那么这样定义一个方法是不是多余或者是错误的?
以下是class方法,它们是等价的:
def User.digest(string)
# MY LOGIC
end
def self.digest(string)
# MY LOGIC
end
Class 方法直接在 class 上调用,例如 User.digest("my_string")
。
We are in the User class so every method in it should be accessible by User.
不幸的是,这不是真的。使用 User.<method_name>
.
只会调用 class 方法
如果你定义了一个方法
def digest(string)
# MY LOGIC
end
以上是一个 实例方法 ,将在 User
class 的实例(对象)上调用(不是直接在 class ) 如:
user = User.new
user.digest("string")
如果你这样做def digest(string)
,你实际上是在定义一个实例方法。
在此处阅读有关 class 和实例方法的更多信息:http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/
Michael Hartl 实际上在底部解释了为什么他以这种方式定义 class 方法(第 8.6 节第 1 点)。
...we defined the new token and digest class methods by explicitly prefixing them with User. This works fine and, because they are actually called using User.new_token and User.digest, it is probably the clearest way to define them....
定义用户 class 方法的其他替代方法是:
def self.digest(string)
#your code here
end
或
class << self
def digest(string)
#your code here
end
end
希望对您有所帮助!我也通过他的书学习了 Rails :)
我目前正在学习 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)
...
我们在用户 class 中,因此 User.<method_name>
应该可以访问其中的每个方法。那么这样定义一个方法是不是多余或者是错误的?
以下是class方法,它们是等价的:
def User.digest(string)
# MY LOGIC
end
def self.digest(string)
# MY LOGIC
end
Class 方法直接在 class 上调用,例如 User.digest("my_string")
。
We are in the User class so every method in it should be accessible by User.
不幸的是,这不是真的。使用 User.<method_name>
.
如果你定义了一个方法
def digest(string)
# MY LOGIC
end
以上是一个 实例方法 ,将在 User
class 的实例(对象)上调用(不是直接在 class ) 如:
user = User.new
user.digest("string")
如果你这样做def digest(string)
,你实际上是在定义一个实例方法。
在此处阅读有关 class 和实例方法的更多信息:http://www.railstips.org/blog/archives/2009/05/11/class-and-instance-methods-in-ruby/
Michael Hartl 实际上在底部解释了为什么他以这种方式定义 class 方法(第 8.6 节第 1 点)。
...we defined the new token and digest class methods by explicitly prefixing them with User. This works fine and, because they are actually called using User.new_token and User.digest, it is probably the clearest way to define them....
定义用户 class 方法的其他替代方法是:
def self.digest(string)
#your code here
end
或
class << self
def digest(string)
#your code here
end
end
希望对您有所帮助!我也通过他的书学习了 Rails :)