我有一个名为dimensions
的属性,我想根据我的width
,height
和depth
属性进行设置。
例如,我想ShippingProfile.find(1).width = 4
,并将其保存为{:width => 4,:height => 0,:depth => 0}`
这可能吗?
class ShippingProfile < ActiveRecord::Base
after_initialize :set_default_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
end
答案 0 :(得分:7)
非常如此,您需要做的就是使用回调来设置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
这样,您可以保留功能并获得一些灵活性。
答案 1 :(得分:0)
ShippingProfile.find(1).dimensions[:width] = 4
答案 2 :(得分:0)
您可以在序列化中使用类,所以
class ShippingProfile < ActiveRecord::Base
serialize :dimensions, Dimensions
end
class Dimensions
attr_accessor :width, :height,:depth
def initialize
@width = 0
@height = 0
@depth = 0
end
def volume
width * height * depth
end
end
现在你可以做ShippingProfile.dimensions.width = 1及以后的ShippingProfile.dimension.volume等。
模型将比Hash
更丰富