What's New in Edge Rails: ActiveRecord Caching Provided in Actions 10

Posted by ryan
at 9:36 PM on Wednesday, February 21, 2007



The flavor du jour in edge rails is definitely caching (see here and here). Some of yas commented on how it seemed kind of hackish to add these caching statements in the view, or even as a filter around your controller actions. Well, now ActiveRecord caching is enabled by default for all your controller actions.

What I don’t yet see is an easy way to disable this caching in your actions. Is there even a case where you want to disable this? Just thinking out loud here…

tags: rubyonrails, rails

Comments

Leave a response

  1. Rob SanheimFebruary 22, 2007 @ 12:42 AM

    How about if you aren’t using a database? Will AR caching fail because it expects one?

  2. ArjenFebruary 22, 2007 @ 05:13 AM

    I was already wondering why caching was explicit instead of implicit, and couldn’t come up with a good reason. Great change!

  3. Dave HooverFebruary 22, 2007 @ 07:52 AM

    @Rob: The Caching module on ActionPack checks to see if ActiveRecord is defined before it turns on ActiveRecord caching.

  4. TobiFebruary 22, 2007 @ 09:27 AM

    If you come up with a reason why you want to disable the caching i’ll implement it :)

    The current implementation is pretty liberal with flushing its cache.

  5. crayzFebruary 26, 2007 @ 12:10 AM

    Tobi – I have multiple applications which use Rails for the front-end web interface, but have some behind-the-scenes PHP scripts pulling in data and updating the database

    How could I disable or force-clear the cache in a situation like that?

  6. Ryan DaigleFebruary 26, 2007 @ 01:15 PM

    crayz: Remember that since Rails is single threaded these caches are ony in effect for the scope of a single request. So the caches will be torn down after every request – I doubt you have long running requests that need to be made aware of external changes to the db?

    In either case, you can force the cache to clear with:

    ActiveRecord::Base.query_cache.clear_query_cache

  7. dseverinFebruary 27, 2007 @ 07:47 PM

    Caveats:

    1. if query returns single value which is immediate (Numeric, FalseClass, TrueClass) caching breaks (see for example http://dev.rubyonrails.org/ticket/7661 )

    2. with caching following code:

    foo = Model.find( 1 ) # from DB bar = Model.find( 1 ) # from cache bar.baz_field << ” boo! “

    will also update value of foo.baz_field

    though these are extremely rare edge cases

  8. mayoMarch 05, 2007 @ 12:21 AM

    It doesn’t seem to play nice with transactions or AR calculations (haven’t fully tracked it down yet). I have a case where view wants to render a value (<%= model.value %>, the model defines value as associated.sum(‘field’)). The value is a calculated value and I’m rolling a transaction back before rendering the view. The view will render cached value, which is in my case incorrect. Basically the value is increased by an amount inside of the transaction, and then the txn is rolled back. The value rendered will be the value before rollback, not after rollback. If I stick a breakpoint right before/after the value in the view and check the value from breakpointer, it returns the correct value, however the correct value in this case comes from sql, no cache is used; the wrong value is still rendered though.

    I still need to track it down more and limit the variables a bit … but generally I removed all other code that could be affecting this.

  9. Walther H DiechmannDecember 22, 2007 @ 09:15 AM

    I have to start this comment by confessing my uther newbiness railswise = probably rendering the rest of this comment useless. For that I apologize!

    Caching – even on a single request – is good if you SELECT :advanced_query and have 250,000 rows returned, and then decides to display only the first 25 rows. The exact same query could return 12 rows on another request, and of cause display all rows.

    In both requests you’d like to display the number of rows available.

    In my “PHP days” I’d have to do the SELECT twice – once to get the total number of rows, and a second time with an added “LIMIT 1,25”

    If caching will let me spare the rDBMS of the second SELECT – then caching is just what the doctor ordered ;)

  10. MichaelMarch 17, 2008 @ 04:21 PM

    Caching is breaking my SQLServer interaction from Rails which worked prior to updating the app to Rails 2.0.

    The SQLServer adapter uses “SELECT @@IDENTITY as Ident” after every INSERT statement in order to get the ID of the just-inserted row.

    Unfortunately, AR hits cache for this value despite claims that every INSERT causes the cache to be cleared.

    For the immediate term, I can afford to disable results caching on a global basis—if I could figure out how! For the longer term, it might be nice to be able to tell the QueryCache not cache specific queries, e. g. see above cause of angst.

Comment