2014-01-07 30 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的。您可以看到,这一切都发生在购买或调整模型中的过滤器之前,而不是真正通过每个说法的关系。所以我不确定你的答案是说我应该改变它的工作方式,或者你没有注意到它是如何完成的。我对这个东西没有自负心,是一个永远的学生,所以请说我是否做错了。 :-) 谢谢! –