The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
counter_cache sneakiness

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Obie Fernandez

Posts: 608
Nickname: obie
Registered: Aug, 2005

Obie Fernandez is a Technologist for ThoughtWorks
counter_cache sneakiness Posted: Nov 25, 2006 12:13 AM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Obie Fernandez.
Original Post: counter_cache sneakiness
Feed Title: Obie On Rails (Has It Been 9 Years Already?)
Feed URL: http://jroller.com/obie/feed/entries/rss
Feed Description: Obie Fernandez talks about life as a technologist, mostly as ramblings about software development and consulting. Nowadays it's pretty much all about Ruby and Ruby on Rails.
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Obie Fernandez
Latest Posts From Obie On Rails (Has It Been 9 Years Already?)

Advertisement

The Question

Given this pair of ActiveRecord models:

class Firm < ActiveRecord::Base
  has_many :votes
end

class Vote < ActiveRecord::Base
  belongs_to :firm, :counter_cache => :vote_total
end

And this test case:

class FirmTest < Test::Unit::TestCase
  
  fixtures :firms, :votes

  def test_vote_total_should_increment_when_new_session_reports
    firm = firms(:first)
    assert_equal 4, firm.vote_total
    firm.report('experimental','aaaaa','')
    assert_equal 5, firm.vote_total
  end
end

Why did I spend more time than I care to admit this evening trying to figure out if the :counter_cache option for belongs_to is broken?

The Answer

I'm guessing if you know the answer it's because you've been bitten by this little gotcha already. I figured it out by examining the test coverage for this feature of ActiveRecord:

  def test_counter_cache
    topic = Topic.create :title => "Zoom-zoom-zoom"
    assert_equal 0, topic[:replies_count]
    
    reply = Reply.create(:title => "re: zoom", :content => "speedy quick!")
    reply.topic = topic

    assert_equal 1, topic.reload[:replies_count]
    assert_equal 1, topic.replies.size

    topic[:replies_count] = 15
    assert_equal 15, topic.replies.size
  end

See that sneaky call to reload?

The revised test for my code, which did finally pass:

   def test_vote_total_should_increment_when_new_session_reports
    firm = firms(:first)
    assert_equal 4, firm.vote_total
    firm.report('experimental','aaaaa','')
    
    # Annoying that firm has to be reloaded here
    # but in practice doesn't hurt anything, since requests that
    # alter the total will be redirected, which reloads firm anyway.
    assert_equal 5, firm.reload.vote_total
  end

What do you think?

Is the need to invoke reload to pickup the up-to-date value for the counter cache a bug or a feature?

Read: counter_cache sneakiness

Topic: Retrieving Files With Capistrano Previous Topic   Next Topic Topic: Howto Use Vim With Rails in Ruby on Rails

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use