Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Activerecord Rails 4.0.3:after_save回调调用得太早了吗?_Activerecord_Ruby On Rails 4_Callback - Fatal编程技术网

Activerecord Rails 4.0.3:after_save回调调用得太早了吗?

Activerecord Rails 4.0.3:after_save回调调用得太早了吗?,activerecord,ruby-on-rails-4,callback,Activerecord,Ruby On Rails 4,Callback,考虑到下面两个类Customer和Order,我有一个问题,我已经将问题缩小到我正在使用的回调的执行时间 使用回调的原因是,我需要存储每个客户的聚合差异,而不必每次迭代他/她的所有订单。因此,我意识到使用回调可能是一种好方法,首先在每次保存之前更新每个订单上的差异,然后在每次保存订单之后更新客户模型上的聚合差异 我得到的症状是奇怪的、看似随机的错误,它告诉我两份订单之间的差额(总计238美元)是15美元。当我将调试器限制在受影响的客户时,我意识到它只是跳过下面的orders.each循环(但仅在

考虑到下面两个类Customer和Order,我有一个问题,我已经将问题缩小到我正在使用的回调的执行时间

使用回调的原因是,我需要存储每个客户的聚合差异,而不必每次迭代他/她的所有订单。因此,我意识到使用回调可能是一种好方法,首先在每次保存之前更新每个订单上的差异,然后在每次保存订单之后更新客户模型上的聚合差异

我得到的症状是奇怪的、看似随机的错误,它告诉我两份订单之间的差额(总计238美元)是15美元。当我将调试器限制在受影响的客户时,我意识到它只是跳过下面的orders.each循环(但仅在某些情况下),因为没有与客户关联的订单

因为所有客户都至少有一个订单,而且在这个系统中,订单实际上是在客户之前创建的,所以这不可能是真的

在ActiveRecord完成保存订单对象和更新与客户模型的关系之前,是否有某种方法可以强制执行after_save回调函数不被调用

正如您所看到的,我还尝试使用计时器来查看是否可以在继续之前让线程休眠一段时间来开始工作,但这不起作用

class Customer < ActiveRecord::Base

  ...

  has_many :orders
  before_save :calculate_shipping

  def update_total_diff
    sum = 0

    orders.each do |o|
      if o.diff.present?
        sum += o.diff
      end
    end

    # HERE IS THE PROBLEM: When inspecting the orders collection in the debuggger it is empty.

    # Make sure shipping is updated
    calculate_shipping

    # Since we are calculating the diff shipping must be subtracted
    sum -= shipping

    self.total_diff = sum
    self.save
  end

  ...

  private

    def calculate_shipping

      ...returns either 15 or 0

    end

end

你有没有得到更多的信息?对不起,我不记得结果如何,但我想我已经解决了上面的问题。
class Order < ActiveRecord::Base

  ...

  belongs_to :customer
  before_save :update_diff
  after_save :update_customer

private
  def update_diff

    #Updates a local value
    ......

  end

  def update_customer

      #Here we trigger a function on the customer model in order to tell it that it needs to re-calculate

      sleep(1/10) #Tried this to test - no luck

      if self.customer_id.present? && diff.present?
        self.customer.update_total_diff
    end
  end
end
From: /vagrant/app/models/order.rb @ line 23 Order#update_customer:

    21: def update_customer
    22:   if self.customer_id.present?
 => 23:     binding.pry
    24:   end
    25:     if self.customer_id.present? && diff.present?
    26:     self.customer.update_total_diff
    27:   end
    28: end

...

[4] pry(#<Order>)> michael = self.customer
=> #<Customer id: 2, name: "Michael xxx", mail: "xxx@gmail.com", shipping_address_id: 2, created_at: "2014-07-17 11:00:12", updated_at: "2014-07-17 11:00:12", shipping: #<BigDecimal:7fada4e707d0,'0.0',9(36)>, total_diff: nil>
[5] pry(#<Order>)> michael.orders
=> []
[6] pry(#<Order>)> michael = Customer.find(2)
=> #<Customer id: 2, name: "Michael xxx", mail: "xxx@gmail.com", shipping_address_id: 2, created_at: "2014-07-17 11:00:12", updated_at: "2014-07-17 11:00:12", shipping: #<BigDecimal:7fada5008098,'0.0',9(36)>, total_diff: nil>
[7] pry(#<Order>)> michael.orders
=> [#<Order id: 2, pledge_id: 4808304, amount: #<BigDecimal:7fada50fc120,'0.89E2',9(36)>, customer_id: 2, perk_id: 9, created_at: "2013-11-23 00:00:00", updated_at: "2014-07-17 11:00:12", diff: #<BigDecimal:7fada5108240,'0.0',9(36)>>]
[8] pry(#<Order>)>
me = Customer.find(id)

me.orders.each do |o|
  if o.diff.present?
    sum += o.diff
  end
end