我为虚拟属性编写了自定义的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上仍然占有一席之地。很高兴对此予以纠正。
干杯!
答案 0 :(得分:3)
我认为你的方法很好,但我不建议使用eval
,主要是因为已经有更合适的ruby元编程方法来实现这一点。阅读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