2016-07-18 11 views
1

railsモデルのインスタンス変数にアクセスするさまざまな方法について混乱しました。たとえば、これは動作します:railsモデルのインスタンス変数の参照

def add_calories(ingredient) 


    self.total_calories += ingredient.calories 

    p total_calories 

end 

は、しかし、これはエラーになります:

def add_calories(ingredient) 

    total_calories += ingredient.calories 

end 



Error: NoMethodError: undefined method "+" for nil:NilClass 

はまた、これはどちらか動作しません。

def add_calories(ingredient) 

    total_calories = total_calories + ingredient.calories 

end 

私は最初のケースでは、自己せずにインスタンス変数にアクセスできる場合、どのようにそれが第二の場合には、total_caloriesがゼロになってきますか?

total_caloriesのデフォルト値が0に設定されていてもかまいませんか?しかし、その場合、なぜself.total_caloriesが機能しますか?

t.integer "total_calories", default: 0 

私はthis postを読むが、第三の場合は動作しませんなぜそれが本当に説明していません。

ありがとうございます。

+0

ないので、多くのインスタンス変数をここにアクセス属性として。すべての属性は、 '@属性'と呼ばれるinstance_variableに含まれています。これは実際にはハッシュです。明示的なレシーバでゲッターメソッドを呼び出す必要がある理由は他の誰かがその部分を手助けできるかもしれません。 – engineersmnky

+0

私がprintステートメントでそれを使用したとき、明示的なレシーバー "self"のない最初のケース。それで、私は自己がオプションだと思うようになります。しかし、2番目と3番目のケースでは、自己なしでは機能しません。 – whales

答えて

1

これは、Railsでのインスタンス変数アクセスについての質問というよりも、Rubyの「セッター」メソッドに関する質問(あなたの場合は、total_calories=メソッドを使用している)のようです。セッターメソッドに明示的なselfレシーバーが必要な理由についての情報は、this oneのような他のスタックオーバーフローの回答で説明されています。

要約すると、問題は文total_calories = somethingの意図があいまいである可能性があるということです:新しいローカル変数を定義しているのか、セッターを呼び出していますか? self.total_calories = somethingを呼び出すと、セッターを呼びたいと明言していますが、selfのままにしておき、total_calories = somethingを呼び出すと、新しいローカル変数が必要です。

は、私はあなたが明示的に両方のgetterメソッドとsetterメソッドを使用する方法の内容を変更する場合は、あなたの第三の例では、動作するはずだと思う:

def add_calories(ingredient) 
    self.total_calories = total_calories + ingredient.calories 
end 
関連する問題