2016-11-20 8 views
1

私はRailsを学んでおり、公式guidesを通って、私は実際にその意味を理解できないコードを見つけました。RailsのRuby構文の解説

ケース1 -

class Person < ApplicationRecord 
    validates :name, presence: true 
end 

それはvalidates引数として:nameと呼ばれるシンボルを取る方法であるように私には見えます。しかし、presenceとは何ですか?それはまた方法ですか?しかし、それがある場合は、の意味はpresenceの直後になります。値truepresenceに設定されていることを理解しています。これはバリデーションの一種であり、(つまり、)存在を必要としています。しかし、私は構文についてはっきりしていません。

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

ルビの括弧が(オプション)欠けている理由は、時には読みやすくなるからです。例えば、 'puts(" hi ")'や 'refute 'ではなく' puts "hi" 'これは' 'refute(" This ".equals?(" That "))'ではなく、最小値)。また、比較演算子をメソッドにすることもできます。例えば、 'a == b'は' a。==(b) 'と同じものです。このメソッドはオーバーライド/変更できます。 – thesecretmaster

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パターンなので、ここで何が起こっているのかよく分かります。オプションを取る独自のメソッドを書いてみてください、そして、あなたはそれがどのように再生するか見るでしょう。

+1

詳細情報をありがとう!私は 'splat'演算子について読みました - ' * '、今すぐ' ** 'を調べなければなりません! –

+0

この回答は私よりもはるかに詳細です。私は '** arg'が有効な構文であることさえ知りませんでした。ありがとう! – thesecretmaster