Difference between “count” and “length” in Rails.

I made an interesting discovery the other day between how “count” and “length” function with an ActiveRecord model, one that can be exploited effectively to speed up an app, as long as you understand the consequences.

  • Invoking “count” on an array (or dependent relationship) will always hit the database, and do something similar to select count(id) as count_all from contacts every time you invoke it.
  • Invoking “length” on an array (or dependent relationship) will only hit the database once. If the relationship has already been populated (say by :include-ing the dependent objects in your Model.find method), the database won’t get hit at all.

So – if you’re OK not getting a count that’s 100% accurate at the time of method invocation, “length” will do the right thing and run the necessary SQL statement the first time it’s run. Otherwise, it’ll give you the array count, which may be out of sync with the database.

This can have significant performance benefits if you’re iterating through many records and emitting counts of dependent objects. :include-ing the dependent objects and using “length” decreased the SQL expense of a page view 40 fold in one case.

Once again, it’s good to know your tools.

Rails.vim

Frequently a tool crops up that makes me feel foolish for not using it – that tool today is Rails.vim. It rocks in so many ways I am seriously considering having Tim Pope’s babies – were such a thing possible.

  • Automatic method completion!
  • Automatic switching to fixtures, unit tests, and other context-sensitive actions!
  • Excellent syntax highlighting!
  • Hooks into your script/ directory!

And really too much stuff to articulate here. Just use it! Yay for IDEs that don’t slow you down – I’m looking at you, RadRails.

Getting it working under modern Ubuntus (ubunti?) is stupid easy (as a normal user):

 sudo aptitude install vim-rails
 vim-rails-setup

Rails 2.2, postgres, and testing

If you’re using Postgresql with Rails 2.2, your testing database user needs to be a “superuser” for your tests to run. This is not a good thing. It’s the equivalent of running as root. But, if you’ve got a completely separate development/testing server it’s better than not being able to test at all.

If your postgres testing user isn’t a superuser, you’ll get errors like:

ActiveRecord::StatementInvalid: PGError: ERROR:  permission \
denied: "RI_ConstraintTrigger_17866" is a system trigger

You can create a postgres superuser thusly:

> su - postgres
> psql template1
> template1=# create user  your username superuser;

Update the testing stanza of your config/database.yml and you should be good to go.

Public Radio Fundraising Redux

I hereby release this idea to the Public Radio fundraising community:

When an individual contributes during an pledge drive, that individual gets a personalized URL / link / token / podcast whatever that gives them the live broadcast with all fundraising appeals stripped out.

Yeah, it’s not that simple I’m sure. You’d have to either be out-of-sync timewise (to make up for the total time taken up by the fundraising appeals) or you’d have to fill the space with some other content.

I bet this’d be an attractive option to many, though. Rather than the weak “we’ll end the fund drive right now if enough people give” pitch, each individual would end it for themselves when they pony up.

GitTorrent – git repos with distributed file storage.

My mind has been sufficiently blown.

Free software source code hosting with political resiliency baked right in – I guess you’re already immune to political strife when your code is “free as in speech.”  This strikes me as fitting the “trust but verify” adage quite nicely.

The powers that be aren’t going to mess with my perfectly legal free software, but <caveats status=”applied”>restricting my ability to code what I want isn’t going to faze me when it’s replicated across a bajillion nodes. </caveats>