真的很令人沮丧:在rails 4中使用回调验证方法

时间:2016-01-07 20:48:21

标签: ruby-on-rails validation callback

我遇到了这些验证和回调方法的问题。

保存对象后,我想更新关联模型对象的两列,如adjust_inventory回调方法中所示。

但是,如果运行adjust_inventory方法导致units.quantity为< 0,我想阻止创建对象并添加验证错误。

这是我的模型(更新): 注意:我正在使用基于此帖子的deferred_associations gem:http://mikrobi.github.io/validating-has-and-belongs-to-many-associations-with-rails-3/

class Order < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :products
  has_and_belongs_to_many_with_deferred_save :units
  validate :prevent_oversell
  after_create :adjust_inventory



  def adjust_inventory
    units.each do |ad|
      if ad.quantity_sold.blank?
    ad.update_attribute(:quantity_sold, 0)
    end
      new_quant = ad.quantity-1
      new_quant_s = ad.quantity_sold+1
      ad.update_attribute(:quantity, new_quant)
      ad.update_attribute(:quantity_sold, new_quant_s)
    end
  end

  def prevent_oversell
      @arr = []
      self.units.each do |q|
        @arr << q.id
      end

      hash = @arr.inject(Hash.new(0)) {|h,x| h[x]+=1;h}

      self.units.each do |t|
        if t.quantity < hash[t.id] 
         errors[:base] = "Your selection exceeds available inventory. Please check that your size selection matches available inventory"
      end
    end    
  end
end

请帮帮我一个人!!这让我疯狂。

另一个更新:似乎验证正在努力防止导致数量&lt;但是,即使创建了对象(并通过验证),也会显示错误消息。

1 个答案:

答案 0 :(得分:0)

事实证明这完全是我做我想做的事情的错误方式。这实现了我想要的目标:

class Unit < ActiveRecord::Base
  belongs_to :product
  has_and_belongs_to_many :orders
  validates_numericality_of :quantity, :only_integer => true, :greater_than_or_equal_to => 0
end

class Order < ActiveRecord::Base
  has_and_belongs_to_many :users
  has_and_belongs_to_many :products
  has_and_belongs_to_many :units
  before_create :adjust_inventory
  validates_associated :units

  def adjust_inventory
    units.each do |ad|
      if ad.quantity_sold.blank?
         ad.update_attributes(quantity_sold: 0)
      end
      new_quant = ad.quantity-1
      new_quant_s = ad.quantity_sold+1
      ad.update_attributes(quantity: new_quant)
      ad.update_attributes(quantity_sold: new_quant_s)
    end
  end
end