Counter_cache to calculate child entries

The counter cache method can be used to store the number of child items
with ease.
My scheme of things has multiple users adding entries into the child
table. Will the active record handle this? Will the number be updated
accordingly if more than one user simultaneously add child entries?

Roger wrote:

The counter cache method can be used to store the number of child items
with ease.
My scheme of things has multiple users adding entries into the child
table. Will the active record handle this? Will the number be updated
accordingly if more than one user simultaneously add child entries?

No, the counter cache can be set incorrectly if children are added
concurrently. To be sure the counter_cache is updated correctly,
code like:

Parent.transaction do
@parent = Parent.find( …, :from => ‘parents for update’ )
@parent.children.create( params[:child] )
end

Similarly for child deletion.


We develop, watch us RoR, in numbers too big to ignore.

Mark Reginald J. wrote:

No, the counter cache can be set incorrectly if children are added
concurrently. To be sure the counter_cache is updated correctly,
code like:

Parent.transaction do
@parent = Parent.find( …, :from => ‘parents for update’ )
@parent.children.create( params[:child] )
end

That said, as long as you wrap the child creation in a transaction
(if Rails has not already done so internally, as is the case
for creation via the parent association), you’re pretty right
because counter cache updates are done as single-statement updates
in after_create.

It depends on whether you just want your child count to stay correct,
not caring if you read a slightly stale count on occasion, or whether
you want the correct count every time you read it.


We develop, watch us RoR, in numbers too big to ignore.

Roger wrote:

The counter cache method can be used to store the number of child items
with ease.
My scheme of things has multiple users adding entries into the child
table. Will the active record handle this? Will the number be updated
accordingly if more than one user simultaneously add child entries?

On third thoughts:

Yes, the counter cache will correctly handle concurrent child insertions
and removals, but any updates you do to parent objects should be done
in a “select…for update” transaction because the counter cache may be
updated by another request while the object is being found, updated, and
saved.

Really Active Record should be changed so it leaves out counter
cache attributes when doing update saves.


We develop, watch us RoR, in numbers too big to ignore.