2011-09-19 13 views
1

私は(より少ないコードで同様のクラスオブジェクトの属性値をテストするために)次のようにいくつかのspecファイルをリファクタリングしようとしているのRails 3.0.9とRSpecの2にルビーを使用しています:各クラスオブジェクトの属性を値に「プログラムで」「反復的に」設定する方法はありますか?

[ 
    :attribute_a, 
    :attribute_b, 
    :attribute_c 
].each do |attr| 
    before do 
    # HERE I would like to set the "current" 'attr' related to the 
    # class object instance 'attribute_<letter>' (read below for 
    # more information) each time the iterator is called (note: all 
    # following attributes are NOT attr_accesible - for that reason 
    # I use the 'user.attribute_<letter>' in the 'before do' 
    # statement) 
    # 
    # # Iteration 1 
    #  user.attribute_a = 'a_value' 
    # # No changes to 'user.attribute_b' 
    # # No changes to 'user.attribute_c' 
    # 
    # # Iteration 2 
    # # No changes to 'user.attribute_a' 
    #  user.attribute_b = 'a_value' 
    # # No changes to 'user.attribute_c' 
    # 
    # # Iteration 3 
    # # No changes to 'user.attribute_a' 
    # # No changes to 'user.attribute_b' 
    #  user.attribute_c = 'a_value' 

    # Maybe I should make something like the following but that, as well 
    # as the 'send' method must be used, doesn't work (the below code-line 
    # is just an example of what I would like to do). 
    # 
    # user.send(:"#{attr}") = 'a_value' 
    end 

    ... 
end 

どのように私は上記のコードを改善することができます(私は、に各ユーザーの属性の値を設定する "プログラムで"設定するために、user.send(:"#{attr}") = 'a_value'部分を参照してください)

答えて

1

あなたは.sendを使用するとセッターを呼び出すために、メソッド名に=を追加し、sendに2番目の引数として値を渡す必要があります。

[ 
    :attribute_a, 
    :attribute_b, 
    :attribute_c 
].each do |attr| 
    before do 
    user.send("#{attr}=", 'a_value') 
    end 

あなたはこれを効果的にやっている:

user.send('attribute_a=', 'a_value'); 

いくつかの理由であなたの構文(user.send(:"#{attr}") = 'a_value')が間違っている/間違っています:

  • 彼らはあなたが.send
の戻り値に値を代入することはできませんすぐに戻っシンボル
  • にあり、文字列へ:attrを変換する理由ませんし、
  • 関連する問題