澄清Rails中的Ruby语法

时间:2016-11-20 02:54:01

标签: ruby-on-rails ruby validation syntax

我正在学习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'

感谢您的帮助!

2 个答案:

答案 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模式,所以理解这里发生了什么是很好的。尝试编写自己的方法来获取选项,然后你会看到它是如何发挥作用的。