【发布时间】:2012-12-14 19:30:48
【问题描述】:
在我的表单中,我有一个虚拟属性,允许我接受混合数字(例如 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,它具有虚拟属性: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。
【问题讨论】:
标签: ruby-on-rails