正是这样,所有你需要做的是使用一个回调来设置self.dimensions值:
class ShippingProfile < ActiveRecord::Base
after_initialize :set_default_dimensions
after_validation :set_dimensions
serialize :dimensions, Hash
attr_accessor :width, :height, :depth
attr_accessible :width, :height, :depth, :dimensions
private
def set_default_dimensions
self.dimensions ||= {:width => 0, :height => 0, :depth => 0}
end
def set_dimensions
self.dimensions = {
:width => self.width || self.dimensions[:width],
:height => self.height || self.dimensions[:height],
:depth => self.depth || self.dimensions[:depth],
}
end
end
您需要使用self.foo || self.dimensions[:foo]
,以确保您保留任何现有值已经在散列中设置。为什么?你的维度属性(我假设)没有被保存在数据库中 - 你正在使用attr_accessor,而不是将它们设置为表中的字段。
顺便说一句,我认为你正在以错误的方式去讨论你的模型设计。通过将维度存储为数据库中的散列值,不仅会失去基于这些属性进行查询的能力,还会增加不需要的脆弱级别。
如果您的是将您的个别维度属性存储为单独的字段,那么您将引入冗余和复杂性。
class ShippingProfile < ActiveRecord::Base
def dimensions
{ :width => self.width, :height => self.height, :depth => self.depth }
end
end
这样,你保留功能:你会被具有三个属性的字段在数据库中(如果你没有的话),然后在飞行中产生的尺寸哈希时,它需要得到更好的服务并获得一些灵活性。
您不觉得ShippingProfile.find(1).dimensions.width = 4会更好吗? – macarthy 2011-02-10 02:06:21