1

仮想属性のカスタマイズされた getter メソッドと setter メソッドを作成して、データベースに格納するために小数を整数に変換しました。これは、データベース内の実際の属性 (annual_fee) から取得/設定する 3 つの仮想属性 (annual_fee_dollars) の 1 つです。

def annual_fee_dollars
  @annual_fee_dollars || int_to_dec(annual_fee)
end

def annual_fee_dollars=(string)
  @annual_fee_dollars = string
  self.annual_fee = dec_to_int(string)
end

このすべてのコードを 3 回繰り返す代わりに、次のようにコードをリファクタリングするのは理にかなっていますか / 安全ですか / 'Rails Way' ですか:

def self.decimal_get_and_set(variable, suffix)
  eval (
    "def #{variable + suffix}
      @#{variable + suffix} || int_to_dec(self.#{variable})
    end
    def #{variable+suffix}=(string)
      @#{variable+suffix} = string
      self.#{variable} = dec_to_int(string)
    end")
end
self.decimal_get_and_set "annual_fee", "_dollars"
self.decimal_get_and_set "interest_purchase", "_percent"
self.decimal_get_and_set "interest_cash", "_percent"

または、このタイプの機能を構築するためのよりクリーンな方法はありますか?

これが「主観的な質問」である場合は申し訳ありません。部分的には、すべてのリファクタリングの質問にはある程度の主観がありますが、この質問はまだSOにあると思います. これについて修正されてうれしいです。

乾杯!

4

1 に答える 1

3

あなたのアプローチは問題ないと思いますがeval、主にこれを行うためのより適切なルビーメタプログラミングの方法が既にあるため、を使用することはお勧めしません。define_methodと オブジェクト メソッドinstance_variable_getとのドキュメントを読んでくださいinstance_variable_set

あなたが望むもののように見え、あなた自身を使う必要はありませんeval。私はおそらく次のようなことを提案しますが、その通りです。すべてのリファクタリングの質問は、その性質上、やや主観的です。幸運を!

{'annual_fee' => '_dollars', 'interest_purchase' => '_percent', 'interest_cash' => '_percent'}.each_pair do |variable, suffix|
  # Define getters
  define_method "#{variable+suffix}" do
    instance_variable_get("@#{variable+suffix}") || int_to_dec(send("#{variable}")
  end

  # Define setters
  define_method "#{variable+suffix}=" do
    ...
  end
end
于 2011-05-16T15:57:30.510 に答える