I certainly can’t claim to have discovered these tips; but they’ve been pretty helpful to me. Maybe this will just make them a little easier to find for whoever is looking for them next.
Getting A Collection’s Index From Within a Partial
Lets say you’re passing a collection to a partial, but that somewhere in that partial you are interested in knowing which index you’re at. Do you need to implement a counter? Nope; there already is one. A collection passed to a partial implicitly creates a counter called [partial_name]_counter. So, if you called with
1 | < %= render :partial => 'thing', :collection => @a_few_of_my_favorite_things %> |
then in your partial, you could use:
1 | < %= thing_counter %> |
to return the index as you plow through the collection. Life is good. Rails is looking out for you. (Hat tip to GMarik, which is where I saw this one.)
Obtaining a Class name From a String
Today I found myself wanting to take a string, let’s say "Thing", and use it as a class name, Thing. Again, it turns out this can be done. In Ruby, class names are constants, so you can do
1 2 | str = "Thing" #=> "Thing" Kernel.const_get(str) #=> Thing |
Hooray!
Make Finding Easier
Find yourself writing long, complicated find expressions in your code? There is a better way.
Perhaps in your code… maybe even in a view… maybe you want to find all Things that don’t belong to the current use, and which are flagged with some property, and you’re temped to write something like:
1 | Thing.find(:all, :conditions => ["user != ? and flag = true", current_user]) |
What we could do is put some has_finders in the Thing model, something like
1 2 3 | class Thing < ActiveRecord::Base has_finder :exclude_user, lambda {|user| {:conditions => "things.user_id != #{user.id}"} has_finder :with_flag, :conditions => "things.flag = true" |
Having done that, you could now replace that first bit with:
1 | Thing.find(:all).with_flag.exclude_user(current_user) |
It’s a little shorter, sure, but more importantly, when you read it, it just makes more sense. A completely new person coming to look at this line would have a good idea what it was doing without even looking in the model to see what the has_finders were doing.
Okay then
If you’ve spent any amount of time using rails, these probably aren’t new to you. Everything’s new at least once, though, so hopefully these are helpful to someone.
Other favorite ruby or rails tricks? Leave a comment! Heck, we’re not prejudiced, here, go ahead and comment with your favorite Python or Perl or [other language] tricks, too, if you like.
Those are great tips. Didn't know about the counter and const_get tricks.
One small correction: I think has_finder is actually named_scope in Rails 2.1 (http://dev.rubyonrails.org/changeset/9084)
Thanks for sharing
It looks like you're correct about named_scope, my mistake.
It turns out the Rails project I am working on has the 'has_finder” gem installed in /vendor, and I mistakenly thought that what I was doing was already part of Rails. I'll have to correct the post, thanks!