保存后,counter_cache不在模型上更新

时间:2012-11-24 23:00:53

标签: ruby-on-rails counter-cache

我正在使用counter_cache让MySQL为我做一些簿记:

class Container
  has_many :items
end

class Item
  belongs_to :container, :counter_cache => true
end

现在,如果我这样做:

container = Container.find(57)
item = Item.new
item.container = container
item.save

在SQL日志中会有INSERT后面跟着类似的内容:

UPDATE `containers` SET `items_count` = COALESCE(`items_count`, 0) + 1
    WHERE `containers`.`id` = 57

这是我期望它做的。但是,container[:items_count]将过时!

...除非我container.reload获取更新后的值。在我看来,有点失败了使用:counter_cache支持自定义构建的目的的一部分,特别是因为在我尝试访问reload属性之前我可能实际上不想要items_count。 (由于域逻辑的性质,我的模型代码很重,所以我有时必须在一个控制器调用中保存并创建多个东西。)

我知道我自己可以修补回调,但这似乎是对这个简单功能的一个相当基本的期望。同样,如果我必须编写额外的代码以使其完全正常工作,那么实现自定义计数器可能会更容易。

我在做什么/假设错了?

2 个答案:

答案 0 :(得分:3)

您不应期望在您的Container实例中自动更新items计数器的值。请记住,大多数Rails应用程序在多进程(通常是多服务器)配置中运行。如果一个进程在另一个进程上添加了与Container实例关联的Item,则该计数器的值将变为陈旧。

答案 1 :(得分:1)

你实际上并没有让容器知道这个项目,这实际上就是你在container.reload时所做的事情!它。你试过了吗?

container = Container.find(57)
item = container.items.create()

这将使项目在容器的上下文中为您构建这些关联。