2016-11-20 50 views
1

我在學習Rails,並在通過官方guides,我遇到了一些我無法真正理解其含義的代碼。關於Rails中Ruby語法的說明

案例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

它們只是哈希。你如何格式化取決於你(在Ruby語法的範圍內)。 –

回答

5

這是將散列傳遞給方法的語法。所做的與validates(:terms_of_service, {acceptance: true, message: 'must be abided'})一樣。這是將額外選項傳遞給方法的常用方法。

+0

謝謝!我之前主要使用過Java和JS,所以我習慣了方法周圍的'()'。必須習慣於Ruby中的缺乏。 –

+0

在紅寶石中(可選)缺乏parens的原因是,有時它會更具可讀性。例如:'puts「hi」'而不是'puts(「hi」)''或'駁回「這個」.equals「那個」'而不是''反駁(「this」.equals?(「That」))'( MINITEST)。它還允許比較操作符爲方法,例如'一個== B'是一回事'一個==(B)',並且該方法可以被重寫/修改。 – thesecretmaster

3

在Ruby中,傳遞選項作爲最後一個參數是一個很好的傳統,足夠強大,這個傳統成爲從Python中借用的新特性:關鍵字參數。

在經典紅寶石的方法將被定義爲這樣:

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模式,所以很好理解這裏發生了什麼。嘗試編寫自己的方法來選擇選項,然後你會看到它是如何發揮作用的。

+1

感謝您的詳細信息!我讀過'splat'運算符 - '*',現在必須查看'**'! –

+0

這個答案是比我的更詳細的,我甚至不知道'** arg'是有效的語法。謝謝! – thesecretmaster