【问题标题】:How do I keep two records, for different models, in sync without falling into the callback trap?如何让不同模型的两条记录保持同步而不陷入回调陷阱?
【发布时间】:2013-01-25 19:19:39
【问题描述】:

我希望保持同步的两个模型的属性。

1.9.3p194 :009 > p
 => #<Product id: 19, name: "Long Sleeve Blue", description: "<p>\tLong Sleeve Blue Flannel shirt comes in all siz...", price: 49.99, vendor_id: 12, created_at: "2012-12-15 23:35:05", updated_at: "2013-01-24 19:11:18", image: "shirt.png", sku: "ABC10034"> 
1.9.3p194 :010 > p.piggybak_sellable
 => #<Piggybak::Sellable id: 1, sku: "AR4590", description: "Blue Shirt", price: #<BigDecimal:7fa97cd63ff8,'0.2499E2',18(45)>, quantity: 100, item_id: 19, item_type: "Product", active: true, unlimited_inventory: false> 

两者都有一些相似的属性。

我将创建方面放在一边——一旦创建了新记录,我只需执行after_create

问题在于记录的更新。

如果我调用after_save 并在after_save 调用的方法中执行update_attributes,它会启动无限循环并使应用程序崩溃。

如果我想更新许多列,我该如何实现?

我知道一种解决方案是使用 update_column - 但这仅适用于 1 列。

想法?

【问题讨论】:

  • 我假设如果他们被同步了.....他们有某种类型的关联?为什么不直接引用其他模型的属性?
  • 因为我正在使用 gem - piggybak - 来建立关联,但它不像常规的 AR 关联那么简单,因为 gem 实际上是 Rails 引擎。我在这里探索了一些与此相关的东西 - stackoverflow.com/questions/14517088/…

标签: ruby-on-rails ruby-on-rails-3


【解决方案1】:

您可以在每个after_save 回调中暂时停用另一个模型上的回调,以避免像这样循环。具体操作请看本题第二个回答How to skip ActiveRecord callbacks?

可能看起来像这样:

after_save :update_product

def update_product
  Product.skip_callback(:save, :after, :update_other)
  p = Product.find_by_whatever(self.whatever)
  p.update_attributes(:one => self.one, :two => self.two)
  Product.set_callback(:save, :after, :update_other)
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多