2011-10-12 3 views
3

は、私はいくつかのRailsを比較する必要が次のように、(2.3.11)モデルは前とデータベースの更新後の属性値を、私は私のレコードを検索し、ハッシュ内の既存の属性値を保存することで起動します。文字列ではなくシンボルを使用してRailsモデルの属性にアクセスできないのはなぜですか?

id = params[:id] 
work_effort = WorkEffort.find(id) 

ancestor_rollup_fields = { 
    :scheduled_completion_date => work_effort.scheduled_completion_date 
} 

work_effort.update_attributes(params.except(:controller, :action)) 
#etcetera 

注:私は、ハッシュキーにシンボルを使用する "ベストプラクティス"を遵守しています。

次に、ハッシュとモデル属性の値が一致しない場合に可能な追加ステップを判断するために、モデルとハッシュを取得するメソッドがあります。私はキーとして文字列をハードコーディングすることに気づいた

def rollup_ancestor_updates(work_effort, ancestor_rollup_fields) 
    ancestor_rollup_fields.each do |key, value| 
     model_val = work_effort.attributes[key] #nil 
     #etcetera 

を上記のデバッグでは:これを決定するために、私はモデルで取得するためには、各ループ内で属性値を試してみましたが、私は最初にnilを取得した

work_effort.attribute['scheduled_completion_date'] 

希望する値が返されます。それでは、私の各ブロックに私は、次の試してみました、それが働いた:

model_val = work_effort.attributes[key.to_s] 

これを行うための別の方法がありますか? Ruby/Railsの経験が3ヶ月であれば、規定のベストプラクティスと同じようにシンボルをハッシュキーとして使用するのは混乱しますが、シンボルの.to_sを呼び出してモデル属性を取得する必要があります。他の誰かがこれを経験して、これを回避し、これも混乱していますか?おかげで事前に

答えて

8

ARインスタンスに#attributesを呼び出すと返されるハッシュは、文字列キーがあるため、ハッシュへのインデックスとしてのシンボルがあなたのケースでは機能しません。 Hashというサブクラスがあり、シンボルインデックスを自動的に文字列に変換するHashWithIndifferentAccessと呼ばれています。

非常に頻繁に、HashWithIndifferentAccessインスタンスが発生します。完璧な例は、コントローラとビューコードでアクセスするparams変数です。

は本当にそれだけであなたがしていることと同じことをやっているが、それは舞台裏でそれをしないwork_effort.attributes.with_indifferent_access[key]

を使用してみてください。

+0

これは動作しますが、key.to_sを使用すべきではない理由があるか、ほとんどの人がwith_indifferent_accessを使用する説得力のある議論ですか? –

+0

私は非常に説得力のある理由がなければ、私はkey.to_sを使うだけです。あなたのケースでは、key.to_sは実際にwith_indifferent_accessよりも安いようです。 –

0

次の文字列を使用することもできます。stringify_keys!これはRailsコード全体で広く使用されています。

def rollup_ancestor_updates(work_effort, ancestor_rollup_fields) 
    ancestor_rollup_fields.stringify_keys!.each do |key, value| 
    model_val = work_effort.attributes[key] 
    end 
    #.... 
end 
+0

key.to_sを使用せずにこれをコードサンプルにドロップすると、どうすればこのコードを動作させることができますか?ありがとう。その間、私は他の例(with_indifferent_accessをチェックしていますが、今は他の場所で見ていると思います)。 –

+1

あなたは 'symbolize_keys! 'と言っていたはずです。この考え方は、新しいハッシュを作成しないため、 'with_indifferent_access'を呼び出すよりも優れています。もちろん、文字列と記号キーの両方を使用する必要がある場合を除きます。 –

+0

更新された回答を参照してください:stringify_keys!おそらくもう少し明示されています... – charlysisto

4

独自の属性メソッドを上書きすることができます。あなたがwork_effort.attributesを呼び出すとき

class WorkEffort 
    def attributes 
    super.symbolize_keys 
    end 
end 

あなたWorkEffortクラスを開きその後、あなたはハッシュのキーを象徴しているでしょう。

関連する問題