在我的表单中,我有一个虚拟属性,允许我接受混合数字(例如 38 1/2)并将它们转换为小数。我也有一些验证(我不确定我是否正确处理了这个),如果发生爆炸会引发错误。
class Client < ActiveRecord::Base
attr_accessible :mixed_chest
attr_writer :mixed_chest
before_save :save_mixed_chest
validate :check_mixed_chest
def mixed_chest
@mixed_chest || chest
end
def save_mixed_chest
if @mixed_chest.present?
self.chest = mixed_to_decimal(@mixed_chest)
else
self.chest = ""
end
end
def check_mixed_chest
if @mixed_chest.present? && mixed_to_decimal(@mixed_chest).nil?
errors.add :mixed_chest, "Invalid format. Try 38.5 or 38 1/2"
end
rescue ArgumentError
errors.add :mixed_chest, "Invalid format. Try 38.5 or 38 1/2"
end
private
def mixed_to_decimal(value)
value.split.map{|r| Rational(r)}.inject(:+).to_d
end
end
但是,我想添加另一列wingspan,它具有 virtual 属性:mixed_wingspan
,但我不知道如何抽象它以重用它——我将对几十个输入使用相同的转换/验证。
理想情况下,我想使用类似的东西accept_mixed :chest, :wingspan ...
,它会处理自定义的 getter、setter、验证等。
编辑:
我正在尝试使用元编程重新创建功能,但我在几个地方遇到了困难:
def self.mixed_number(*attributes)
attributes.each do |attribute|
define_method("mixed_#{attribute}") do
"@mixed_#{attribute}" || attribute
end
end
end
mixed_number :chest
这会将胸部设置为“@mixed_chest”!我正在尝试@mixed_chest
像上面那样获取实例变量。