3

我正在使用 acounter_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

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

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

这是我期望它做的。然而,这container[:items_count]将是陈旧的!

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

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

我在做什么/假设错了?

4

2 回答 2

3

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

于 2012-11-26T01:13:43.780 回答
1

您实际上并没有让容器知道该项目,这实际上是您在 container.reload 时所做的!它。你有没有尝试过:

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

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

于 2013-04-15T11:13:09.203 回答