2014-01-07 29 views
1

型號 - Purchaseorder,Purchaseorderadjustments,Productvariant,Location,LocationinventoryRails - 如何在從不同模型過濾之前更改驗證模型?

我將庫存存儲在存儲location_id,productvariant_id和quantity的Locationinventory中。

當我想要創建購買訂單時就會出現這種情況。我正在使用purchaseorderadjustments作爲購買訂單的嵌套屬性。 purchaseorder has_many purchaseordedujustments存儲productvariant_id和數量。

我在使用過濾器之前創建,更新和銷燬相關的locationinventory記錄。除了您可以從沒有可用的位置移除項目並且數量剛剛達到否定位置之外,一切都可以正常運行。我想驗證「From Location」是否有足夠的庫存產品變體轉移到「To Location」。

我做錯了嗎?謝謝!

滑軌3.2.14

Purchaseorder.rb

class Purchaseorder < ActiveRecord::Base 
    attr_accessible :fromlocation_id, :status_id, :tolocation_id, :user_id, :purchaseorderadjustments_attributes 

    belongs_to :user 
    belongs_to :status 
    belongs_to :fromlocation, :class_name => "Location", :foreign_key => :fromlocation_id 
    belongs_to :tolocation, :class_name => "Location", :foreign_key => :tolocation_id 
    has_many :purchaseorderadjustments, :dependent => :destroy 

    accepts_nested_attributes_for :purchaseorderadjustments, allow_destroy: true 

end 

Purchaseorderadjustment.rb

class Purchaseorderadjustment < ActiveRecord::Base 
    attr_accessible :adjustmenttype_id, :productvariant_id, :purchaseorder_id, :quantity 

    belongs_to :purchaseorder 
    belongs_to :productvariant 
    belongs_to :adjustmenttype 

    validates_presence_of :quantity, :message => "You need a quantity for each product." 

    # On creation of a purchaseorderadjustment go ahead and create the record for locationinventory 
    before_create :create_locationinventory 
    def create_locationinventory 
    # Get some info before updating the locationinventory 
    if fromlocationinventory = Locationinventory.find(:first, conditions: { :location_id => purchaseorder.fromlocation_id, :productvariant_id => productvariant_id }) 
     fromlocation_current_quantity = fromlocationinventory.quantity 
    end 
    if tolocationinventory = Locationinventory.find(:first, conditions: { :location_id => purchaseorder.tolocation_id, :productvariant_id => productvariant_id }) 
     tolocation_current_quantity = tolocationinventory.quantity 
    end 

    # Create or update the from locationinventory 
    unless fromlocationinventory.nil? 
     fromlocationinventory.quantity = fromlocation_current_quantity - quantity 
     fromlocationinventory.save 
    else 
     new_fromlocationinventory = Locationinventory.new({ location_id: purchaseorder.fromlocation_id, productvariant_id: productvariant_id, quantity: 0 - quantity }) 
     new_fromlocationinventory.save 
    end 

    # Create or update the to locationinventory 
    unless tolocationinventory.nil? 
     tolocationinventory.quantity = tolocation_current_quantity + quantity 
     tolocationinventory.save 
    else 
     new_tolocationinventory = Locationinventory.new({ location_id: purchaseorder.tolocation_id, productvariant_id: productvariant_id, quantity: quantity }) 
     new_tolocationinventory.save 
    end 

    end 

    #On update of purchaseorderadjustment 
    before_update :update_locationinventory 
    def update_locationinventory 
    # Get some info before updating the locationinventory 
    fromlocationinventory = Locationinventory.find(:first, conditions: { :location_id => purchaseorder.fromlocation_id, :productvariant_id => productvariant_id }) 
    tolocationinventory = Locationinventory.find(:first, conditions: { :location_id => purchaseorder.tolocation_id, :productvariant_id => productvariant_id }) 
    fromlocation_current_quantity = fromlocationinventory.quantity 
    tolocation_current_quantity = tolocationinventory.quantity 

    fromlocationinventory.quantity = fromlocation_current_quantity - quantity + self.quantity_was 
    fromlocationinventory.save 

    tolocationinventory.quantity = tolocation_current_quantity + quantity - self.quantity_was 
    tolocationinventory.save 

    end 

    #On destroy of purchaseorderadjustment 
    before_destroy :destroy_locationinventory 
    def destroy_locationinventory 
    # Get some info before updating the locationinventory 
    fromlocationinventory = Locationinventory.find(:first, conditions: { :location_id => purchaseorder.fromlocation_id, :productvariant_id => productvariant_id }) 
    tolocationinventory = Locationinventory.find(:first, conditions: { :location_id => purchaseorder.tolocation_id, :productvariant_id => productvariant_id }) 
    fromlocation_current_quantity = fromlocationinventory.quantity 
    tolocation_current_quantity = tolocationinventory.quantity 

    fromlocationinventory.quantity = fromlocation_current_quantity + quantity 
    fromlocationinventory.save 

    tolocationinventory.quantity = tolocation_current_quantity - quantity 
    tolocationinventory.save 

    end 

end 

productvariant.rb

class Productvariant < ActiveRecord::Base 
    attr_accessible :barcode, :compare_at_price, :fulfillment_service, :grams, 
        :inventory_management, :inventory_policy, :inventory_quantity, 
        :option1, :option2, :option3, :position, :price, :product_id, 
        :requires_shipping, :shopify_id, :sku, :taxable, :title, :shopify_product_id, :product_title 

    belongs_to :product, primary_key: "shopify_id", foreign_key: "shopify_product_id" 
    has_many :purchaseorderadjustments 
    has_many :locationinventories 

    def product_plus_variant 
    "#{self.product.title} - #{self.title}" 
    end 
end 

locationinventory.rb

class Locationinventory < ActiveRecord::Base 
    attr_accessible :location_id, :productvariant_id, :quantity 

    belongs_to :productvariant 
    belongs_to :location 

end 
+0

哇大量的定製方法! –

回答

1

,因爲我覺得你已經提供了這麼多的代碼,我會寫這個答案,你可能會有些後怕回答者了!

我們的經驗如下:


嵌套

您可以用多種不同的方式

驗證嵌套模型

你的問題是關係到一個accepts_nested_attributes_for傳遞數據 - 你可以直接驗證:

#app/models/purchase.rb 
Class Purchase < ActiveRecord::Base 
    has_many :purchase_items 
    accepts_nested_attributes_for :purchase_items 
end 

#app/models/purchase_item.rb 
Class PurchaseItem < ActiveRecord::Base 
    belongs_to :purchase 

    validates :name, 
      presence: { message: "Your Purchase Needs Items!" } #Returns to initial form with this error 
end 

標準

如果要基於另一個模型conditionally validate,你將不得不使用inverse_of:保留該對象提供整個數據事務:

#app/models/purchase.rb 
Class Purchase < ActiveRecord::Base 
    has_many :purchase_items, inverse_of: :purchase 
    accepts_nested_attributes_for :purchase_items 
end 

#app/models/purchase_item.rb 
Class PurchaseItem < ActiveRecord::Base 
    belongs_to :purchase, inverse_of: :purchase_items 

    validates :name, 
      presence: { message: "Your Purchase Needs Items!" }, 
      if: :paid_with_card? 

    private 
    def paid_with_card? 
     self.purchase.payment_method == "card" 
    end 

end 
+0

嗯。感謝您抽出寶貴的時間!我知道我包含了很多代碼。我這樣做是爲了說明我是如何爲Locationinventory模型做CRUD的。您可以看到,這一切都發生在購買或調整模型中的過濾器之前,而不是真正通過每個說法的關係。所以我不確定你的答案是說我應該改變它的工作方式,或者你沒有注意到它是如何完成的。我對這個東西沒有自負心,是一個永遠的學生,所以請說我是否做錯了。 :-) 謝謝! –