1

我已经为虚拟属性编写了自定义的 getter 和 setter 方法,以将小数转换为整数以存储在数据库中。这是从数据库中的真实属性 (annual_fee) 获取/设置的三个虚拟属性 (annual_fee_dollars) 之一:

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

不是重复所有这些代码三次,它是否有意义/是否安全/是否是“Rails 方式”来重构代码,如下所示:

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,主要是因为已经有更合适的 ruby​​ 元编程方式来执行此操作。阅读文档define_method和对象方法instance_variable_getinstance_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 回答