鉴于以下两个类Customer和Order,我遇到了一个问题,我已经缩小到我正在使用的回调的执行时间。
使用回调的原因是我需要存储每个客户的聚合差异,而不必每次都迭代他/她的所有订单。所以我意识到在每次保存之前使用回调来首先更新每个单独订单上的差异可能是一个很好的方法,其次,在>之后更新客户模型上的聚合差异保存每个订单。
我得到的症状是奇怪的看似随机的错误,它告诉我两个订单之间的差异,总计238美元是15美元。当我将调试器限制在受影响的客户时,我意识到它只是跳过下面的orders.each循环(但仅在某些情况下),因为没有与客户关联的订单。
由于所有客户至少有一个订单,并且订单实际上是在此系统中的客户之前创建的,因此无法实现。
在ActiveRecord完成保存Order对象并更新与Customer模型的关系之前,我是否可以通过某种方式强制执行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>)>
我尝试在Order命令客户重新计算之前停止我的调试器。我尝试将同一个客户两次分配给变量&#34; michael&#34;。如果我简单地用以下内容分配变量: michael = self.customer 该对象不知道其任何相关订单。如果我像这样分配它像activerecord: michael = Customer.find(2) 它会工作。那是为什么?
现在我设法解决了这个问题,但我还是想知道是否有人可以为我解释这种情况?
me = Customer.find(id)
me.orders.each do |o|
if o.diff.present?
sum += o.diff
end
end