2011-02-10 20 views
3

width,height、およびdepthという属性に基づいて設定する属性がdimensionsです。仮想属性に基づいてactiverecord属性を設定します

例えば、私は、ShippingProfile.find(1).width = 4をしたい、それはのような寸法に保存した{:幅=> 4:高さ=> 0:深さ=> 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

ShippingProfile.find(1).dimensions.width = 4は良いでしょうか? – macarthy

答えて

7

ので、すべてを行う必要がself.dimensionsの値を設定するためにコールバックを使用している:あなたは、あなたがいずれかを保存することを確認するためにself.foo || self.dimensions[:foo]を使用する必要が

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 

すでにハッシュに設定されている既存の値。どうして?あなたの次元属性(私は仮定している)がデータベースに永続化されていない - attr_accessorをテーブルのフィールドとして設定するのではなく、使用しています。

私はあなたのモデルデザインについて間違ったやり方をしていると思います。ディメンションをハッシュとしてデータベースに格納することで、それらの属性に基づいてクエリを実行する能力を失うだけでなく、必要のない脆弱性のレベルを追加することができます。

が個別のディメンション属性を別々のフィールドとして格納する場合はとなり、冗長性と複雑さが導入されます。

class ShippingProfile < ActiveRecord::Base 
    def dimensions 
    { :width => self.width, :height => self.height, :depth => self.depth } 
    end 
end 

このように、あなたは、機能を保持:あなたはより良い、それが必要だときに、その場で寸法のハッシュを生成し、(すでにされていない場合)、データベース内のフィールドとして3つの属性を持つことによって提供されるだろう柔軟性を得ることができます。

+0

私は個々の次元を格納するように行った。それははるかに問題が少なく、あなたが言ったように、クエリではるかに柔軟性があります。時には私は、見栄えの良いDBを維持することに追いつくが、それの現実は、私は本当にそれを見ている必要はありません:) – brewster

0
ShippingProfile.find(1).dimensions[:width] = 4 
0

あなたは今、あなたはShippingProfile.dimensions.width = 1以降ShippingProfile.dimension.volumeなどを行うことができ、直列化でそう

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 

をクラスを使用することができます。..

モデルは次のようになりハッシュよりも豊富な表現

関連する問題