문제

I am using a counter_cache to let MySQL do some of the bookkeeping for me:

class Container
  has_many :items
end

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

Now, if I do this:

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

in the SQL log there will be an INSERT followed by something like:

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

which is what I expected it to do. However, the container[:items_count] will be stale!

...unless I container.reload to pick up the updated value. Which in my mind sort of defeats part of the purpose of using the :counter_cache in favor of a custom built one, especially since I may not actually want a reload before I try to access the items_count attribute. (My models are pretty code-heavy because of the nature of the domain logic, so I sometimes have to save and create multiple things in one controller call.)

I understand I can tinker with callbacks myself but this seems to me a fairly basic expectation of the simple feature. Again, if I have to write additional code to make it fully work, it might as well be easier to implement a custom counter.

What am I doing/assuming wrong?

도움이 되었습니까?

해결책 2

You haven't actually made the container aware of the item though, which is effectively what you do when you container.reload! it. Have you tried:

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

This will make the item in the context of the container and build those associations for you.

다른 팁

You shouldn't expect the value of the items counter to be automatically updated in your Container instance. Keep in mind that most Rails applications operate in a multiple process (and often multiple server) configuration. If one process adds an Item that is associated with a Container instance on a different process, the value of the counter will become stale.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top