正是這樣,所有你需要做的是使用一個回調來設置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