我正在学习Rails并且通过官方guides,我遇到了一些我无法理解其含义的代码。
案例1 -
class Person < ApplicationRecord
validates :name, presence: true
end
在我看来,validates
是一种将名为:name
的符号作为参数的方法。但那么,presence
是什么?这也是一种方法吗?但如果是,:
之后presence
的重要性是什么。我理解为true
设置了值presence
,它作为一种验证,需要存在(换句话说)。但我对语法不太清楚。
presence: true
也可能只是一个哈希值,其中:presence
(符号)是键,true
是值。
案例2 -
class Person < ApplicationRecord
validates :terms_of_service, acceptance: true, message: 'must be abided'
end
同样,validates
是将符号:terms_of_service
作为参数的方法。但其余的呢?它是具有2个键值对的散列,有点像{acceptance: true, message: 'must be abided'}
吗?
如果它确实是一个哈希,为什么在每种情况下它都加入validates
方法?为什么不能
validates :terms_of_service
acceptance: true, message: 'must be abided'
感谢您的帮助!
答案 0 :(得分:5)
这是将哈希传递给方法的语法。这样做与validates(:terms_of_service, {acceptance: true, message: 'must be abided'})
是一回事。这是将额外选项传递给方法的常用方法。
答案 1 :(得分:3)
在Ruby中,将选项作为哈希作为最后一个参数传递是一个很强的传统,足够强大,以至于这个传统成为从Python借用的新特性:关键字参数。
在经典Ruby中,方法将定义为:
def validates(*args)
options = args.last.is_a?(Hash) ? args.pop : { }
# args is a list of fields
end
在Ruby 2.3中你可以这样做:
def validates(*args, **options)
# options is automatically any hash-style arguments if present
end
在Ruby 2.0+中你也可以这样做:
def validates(*args, acceptance: false, message: nil)
end
将选项定义为第一类变量。
这是一种常见的Ruby模式,所以理解这里发生了什么是很好的。尝试编写自己的方法来获取选项,然后你会看到它是如何发挥作用的。