基于Stefan's excellent comment...
他们是inheritedclass methods组成一个domain specific language,用于make declarations关于班级。
都是class methods,之所以这么称呼是因为你直接在类上调用then。 self 将成为班级。与在类的实例上调用的实例方法相反,对象是对象。
它们也是从ActiveRecord继承的方法,它们是
未在您的类中定义,而是在祖先类或模块中定义。
更具体地说,它们构成了一种领域特定语言; DSL。这些是以特定方式编写的方法调用,看起来像是一门新语言。例如,
class Player < ApplicationRecord
validates :terms_of_service, presence: true, acceptance: { message: 'must be abided' }
end
真的……
Player.validates(
:terms_of_service,
presence: true,
acceptance: { message: 'must be abided' }
)
这是一个包装...
Player.validates_presence_of(:terms_of_service)
Player.validates_acceptance_of(:terms_of_service, message: 'must be abided')
这是一个包装...
Player.validates_with(PresenceValidator, :terms_of_service)
Player.validates_with(AcceptanceValidator, :terms_of_service, message: 'must be abided')
这是一个将验证对象推送到此类验证哈希的包装器。
# Roughly...
Player._validators[:terms_of_service] <<
PresenceValidator.new(
attributes: [:terms_of_service]
)
Player._validators[:terms_of_service] <<
AcceptanceValidator.new(
attributes: [:terms_of_service],
message: 'must be abided'
)
最后,领域特定语言是declarative programming 的形式。
在其他类型的编程中,您告诉程序如何去做。例如,假设您想确保属性是大于零的正整数。您可以按程序进行...
object.number.match?(/^\d+$/) && object.number > 0
或者你要求一个特定的方法来做......
NumericalityValidator.new(
attribute: [:number],
only_integer: true, greater_than: 0
).validate(object)
但在声明式编程中,你声明它会如何,而语言会弄清楚如何实现它。
class Player < ApplicationRecord
validates :number, numericality: { only_integer: true, greater_than: 0 }
end
您可能已经知道两种声明性语言:SQL 和正则表达式。