A Fresh Cup is Mike Gunderloy's software development weblog, covering Ruby on Rails and whatever else I find interesting in the universe of software. I'm a full-time Rails and iOS developer.


A Fresh Cup

Notes on Rails and other development


Double Shot #401

Hooray for Friday.

  • Why You Should Deploy Your Next Application on Ruby 1.9 and a Rant in General - Wishing for better open source release management. Dream on.

  • 7 Fresh and Simple Ways to Test Cross-Browser Compatibility - Some of these look pretty cool.

  • Client-side Caching & Advanced HTTP Caching - Advanced knowledge from Gregg Pollack.

  • live-validations - Takes validations from your Rails models and makes them available to javascript (hooked up to jQuery so far) on the client side.
  • Thursday

    Double Shot #400

    400 of these? Really? I guess this Rails stuff must be sticking around.

  • $100 Linux wall-wart launches - I have no earthly use for one of these. Doesn't stop me from wanting one.

  • Rails 2.3 Nested Object Forms: I’m not Crazy about Them - Some critique of a major new Rails 2.3 feature. Note that there are some changes in the feature for edge, though.

  • Ruby on Rails Integration Testing with Integrity - A good intro to one of the chunks of CI software out there.

  • Native habitat - This is where Double Shot comes from.
  • Tuesday

    Double Shot #399

    The hours from about 4 to 6 AM are the "kid-free productivity zone" for me at the moment.

  • The RSpec Book - Beta 2.0 - I keep meaning to find the time to read this.

  • Cloud Files support coming soon! - Jungle Disk is getting more flexible.

  • Cherokee - Aren't there enough web servers out there? Apparently not.

  • Net::SSH, Capistrano, and Saying Goodbye - Jamis Buck is stepping down as maintainer of some key projects. Be interesting to see what happens next.
  • Tuesday

    Double Shot #398

    The amazing thing is that Rails is still fun even after all this time.

  • How To Start A Rails Edge App The Easy Way - Complete with a crash course in git submodules.

  • Building and Scaling a Startup on Rails: 12 Things We Learned the Hard Way - An excellent collection of lessons learned.

  • query_reviewer - Inline performance testing and analysis for SQL queries in Rails applications.

  • APIdock in TextMate - A wish come true.

  • Another look at integrating Scribd with your Rails application - Ben Curtis shows off complete server and client side integration.

  • Track Your Daily Goals With Twitter - One of my little side projects garners some recognition. Thanks WWD!

  • Log Rotation for Phusion Passenger - Another of those tiny chores you should remember when setting up a server.

  • Google Data on Rails - Google are out with a library to make their various data APIs easily available to a Rails application.
  • Monday

    Rails 2.3: Batch Finding

    If you've ever worked with a huge number of Active Record objects and watched your server memory at the same time, you may have noticed considerably bloat in your Rails processes. That's because Active Record doesn't support database cursors (alas!) so all of those records come into memory at once.

    In Rails 2.3, ActiveRecord::Base is adding two methods to help with this problem: find_in_batches and each. Both of these methods return records in groups of 1000, allowing you to process one group before proceeding to the next, and keeping the memory pressure down:

    find_in_batches is the basic method here:

    [sourcecode language='ruby']
    Account.find_in_batches(:conditions => {:credit => true}) do |accts|
    accts.each { |account| account.create_daily_charges! }

    find_in_batches takes most of the options that find does, with the exception of :order and :limit. Records will always be returned in order of ascending primary key (and the primary key must be an integer). To change the number of records in a batch from the default 1000, use the :batch_size option.

    The each method provides a wrapper around find_in_batches that returns individual records:

    [sourcecode language='ruby']
    Account.each do |account|

    A couple of caveats: first, if you're trying to loop through less than 1000 or so records, you should avoid the overhead of batches and use something like Account.all.each or a regular finder to get the records. Second, if the table is very active (i.e., has a constant stream of inserts and deletes), using the batch methods may miss records due to changes in the table between batches (whereas finding all records will at least give you a complete point-in-time snapshot).