Digging It Up with Dave Thomas
mental note: I should liveblog like Giles did. His terse notes are incredibly readable. I don’t know that my additional pass does anything but delay getting it out there.
One of the most, if not the most, information-dense presentation was Dave Thomas’ “Buried Treasures: Hidden Rails Tips.” It’s a bit of a misnomer; some of the best learning I had was about TextMate
PLEASE NOTE: the code below is pseudocode only. It will not run. If you try to run this code, it will likely cause all of your pet’s hair to fall out.
with_scope
Apply scoping conditions, etc., to ActiveRecord finds. Two interesting ways to call this:
with_scope.(:find => {:readonly => true}, :create => {…}, :conditions, :order, :limit )
… or …
LimitNotExceeded = {:conditions => '...', ...}NotExpired = {:conditions => '...', ...}with_scope(LimitNotExceeded) do with_scope(NotExpired) do find(:all) endend
with_options
Great for DRYing up your routes file ( Jamis Buck agrees), but as it’s available on all Ruby objects you could use this to factor out repeated options in any block of code.
returning
This is awesome. Change this crappy construction:
def badly_coded(foo) status = foo.do_that_thing(:with_that_stuff) unless status unless status = foo.do_some_recovery_thing logger.warning("That didn't go right ...") end end statusend
… to this nifty, readable one:
def shiny_shiny(foo) returning foo.do_that_thing(:with_that_stuff) do |status| unless status = foo.do_some_recovery_thing logger.warning("That didn't go right ...") end endend
each_with_index
Yeah, everyone but me knew about this one, but it’s one I’ve wished for in Perl and Python so it’s nice to have tripped over it in passing. [As Drew points out in the comments, Python has a form of this.]
Lookup Constants
I have a cryptic note “Use them for compile time caching” and I don’t have the slides handy so I can’t decrypt right now.
Don’t Call Models in Migrations
IIRC, this came from a quick side discussion: to avoid the race condition where a model column you need to manipulate might not exist in the database quite yet, you should recreate the model object in the migration rather than call it through ActiveRecord. This bit me a while back and I hacked around it with far less grace.
Date Formats
There are some built-ins:
Time.now.to_s(:db)Time.now.to_s(:short)Time.now.to_s(:long)Time.now.to_s(:rfc822)
You can add your own:
Time::DATE_FORMATS.merge!(:timestamp => '%Y%m%d.%H%M%S')Time.now.to_s(:timestamp)=> "20070827.122334"
You should never need strftime again. =]
BTW, (now..then).to_s(:db) makes a proper BETWEEN clause. Sweet!
Partitioning Groups: group_by
>> (1..20).group_by {|n| n % 3}=> {0=>[3, 6, 9, 12, 15, 18], 1=>[1, 4, 7, 10, 13, 16, 19], 2=>[2, 5, 8, 11, 14, 17, 20]}
Related are index_by and in_groups_of.
Groovy String Tricks
str = "Ruby on Rails"str.at(3)str.from()str.to()str.first()str.last()str.each_char {...}%w{Foo Bar Baz}.to_sentence(:connector => 'and also')
generate + svn
Don’t forget to add/remove your generated bits again.
script/generate model foo --svnscript/destroy model foo --svn
Groovy console Tricks
You can create a custom .irbrc file to preserve command history, etc. Dave said he’d post his; until then, here’s Blaine Cook’s, an exploded view of Dr. Nic’s, and a clever method finder to pop into your .irbrc [irbrc file]
Good to remember that you have an instance of the integration testing ApplicationController as “app”. Mike Clark blogged a bit about this last year. Handy.
A headslapper, in retrospect: you can call irb SomeClass or irb my_object to invoke a subsession inside the scope of that class or instantiated object. I think I’ve got that right.
And reinforcing Giles’ observations, reload! is handy to for getting your code changes into your current console, but it doesn’t reload instantiated objects … so it may not net out. Still, good tool to have handy.
_ I’m going to leave out the TextMate shortcuts as I’ve spent too long on this post already. I mentioned this was info-dense, right? ;] _
Hey Technorati! Get this: therailsedge railsedge railsedge2007
blog comments powered by Disqus