<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>something learned</title>
    <link>http://www.somethinglearned.com/</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>something learned</description>
    <item>
      <title>Ack.tmbundle: a faster &amp;quot;Find in Project&amp;quot; for TextMate</title>
      <description>&lt;p&gt;Recently one of my &lt;a href="http://entp.com"&gt;ENTP&lt;/a&gt; colleagues switched me on to &lt;a href="http://petdance.com/ack/"&gt;ack&lt;/a&gt; as an excellent replacement for find+grep.  Being a dyed in the wool TextMate user, the first thing that popped into my head was &amp;#8220;I need an &amp;#8216;Ack in Project&amp;#8217; TextMate plugin&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Unfortunately the only advertised plugin I could find was 404&amp;#8217;ing on me.  Did I do the simple thing and notify the author about the dead link?  Nope.  I wrote my own plugin instead.&lt;/p&gt;


	&lt;p&gt;In hindsight I have to ask&amp;#8230; what on earth was I thinking?&lt;/p&gt;


	&lt;p&gt;Whatever.  I wrote the plugin and (if I do say so myself) it&amp;#8217;s pretty damn good.&lt;/p&gt;


	&lt;p&gt;Here&amp;#8217;s some installation instructions for getting it from my &lt;a href="http://github.com/protocool/ack-tmbundle/tree/master"&gt;github repository&lt;/a&gt;:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
cd ~/Library/Application\ Support/TextMate/Bundles
git clone git://github.com/protocool/ack-tmbundle.git Ack.tmbundle
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;I&amp;#8217;ve also thrown together a little (silent and slightly crappy) &lt;a href="http://protocool.com/demos/ack_tmbundle.mov" target="_blank"&gt;screencast&lt;/a&gt; showing it in action.&lt;/p&gt;


	&lt;p&gt;Enjoy.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Edit:&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ve updated the wiki to include some information on getting ack to &lt;a href="http://github.com/protocool/ack-tmbundle/wikis/recognizing-files"&gt;recognize new file types&lt;/a&gt; using &lt;a href="http://henrik.nyh.se/"&gt;Henrik&amp;#8217;s&lt;/a&gt; haml comment as an example.&lt;/p&gt;</description>
      <pubDate>Tue,  3 Jun 2008 15:19:39 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2008/06/03/ack-tmbundle-a-faster-find-in-project-for-textmate</guid>
      <link>http://www.somethinglearned.com/articles/2008/06/03/ack-tmbundle-a-faster-find-in-project-for-textmate</link>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/38</trackback:ping>
    </item>
    <item>
      <title>Giant Robots Giving Me Flashbacks.</title>
      <description>&lt;p&gt;This morning I checked my feed reader and was instantly transported back to 1992, when I was working for a small independent software vendor.&lt;/p&gt;


	&lt;p&gt;So please indulge me while I tell you a little bit about the company, what I learned, and what brought it all rushing back.&lt;/p&gt;
&lt;h2&gt;The (un-named) Company&lt;/h2&gt;


	&lt;p&gt;At its peak I believe there were close to 200 people actively developing, porting and translating the company&amp;#8217;s software.  The remaining 300 people (including me) did support, sales and training.&lt;/p&gt;


	&lt;p&gt;The product itself was enormous and ran on hundreds of versions and flavors of Unix.  In fact, the company was so good at development and porting that they often entertained visitors from other independent software vendors who were desperate to learn how to do it well.&lt;/p&gt;


	&lt;p&gt;Even though my job allowed me to do &lt;em&gt;some&lt;/em&gt; development and customization work, my primary role was a post-sales support engineer.  I was desperate to be a &amp;#8216;proper&amp;#8217; software developer so I enthusiastically attended any &amp;#8220;brown bag lunch&amp;#8221; talks that had to do with core product development.&lt;/p&gt;


	&lt;p&gt;Two of those talks, given one week after the other, are still fresh in my mind 15 years later.&lt;/p&gt;


	&lt;h2&gt;Week 1&lt;/h2&gt;


	&lt;p&gt;The first was a talk given by the company&amp;#8217;s Chief Architect on the topic of &amp;#8220;Object Orientation and C++&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Now, I had no formal development training and this was my first &amp;#8216;real&amp;#8217; industry job so I have no idea how popular &amp;#8220;Object Orientation&amp;#8221; was at the time for the industry as a whole.  Of course, today it&amp;#8217;s pedestrian.   But at the time, in that room, it was revolutionary.&lt;/p&gt;


	&lt;p&gt;Inheritance, public, private&amp;#8230; my head was spinning.  It wasn&amp;#8217;t just a new syntax, it was a different way of approaching the problem.&lt;/p&gt;


	&lt;p&gt;In my beginner&amp;#8217;s mind, there was just no contest between K&amp;#38;R C and C++.  I &lt;em&gt;instinctively&lt;/em&gt; understood object-oriented code &amp;#8211; it was virtually self-documenting.&lt;/p&gt;


	&lt;p&gt;This talk was very well received and I can remember ranting to a colleague: &amp;#8220;It just makes sense! If you want to talk to a printer you just create a Printer object.  Here&amp;#8217;s the functions you can call, here&amp;#8217;s the stuff you can&amp;#8217;t touch.&amp;#8221;&lt;/p&gt;


	&lt;h2&gt;Week 2&lt;/h2&gt;


	&lt;p&gt;The very next week, the lead software developer for the company gave a talk  on &amp;#8220;Object Orientation, C++ and [Company Name]&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Boy was I stoked.  I expected to learn about how the propellerheads were going to retool everything (back then I didn&amp;#8217;t know how frightful that idea is) for C++.&lt;/p&gt;


	&lt;p&gt;The talk was shocking and confusing.  For a solid hour he ripped into the ideas that had been presented in the previous week, knocking them down one by one.&lt;/p&gt;


	&lt;p&gt;I can paraphrase his talk like this:&lt;/p&gt;


&lt;blockquote&gt; 

	&lt;p&gt;There is nothing that C++ offers that well-written K&amp;#38;R C doesn&amp;#8217;t offer.&lt;/p&gt;


	&lt;p&gt;If you name your structs, variables and methods correctly then your intentions will be communicated just as effectively as using C++ syntax.&lt;/p&gt;


	&lt;p&gt;If you want to bind functions to data then put function pointers in structs.&lt;/p&gt;


	&lt;p&gt;Any programmer worth his salt will have a solid set of practices for software development based on K&amp;#38;R C and there is no point moving to a new language for features that you either don&amp;#8217;t need or already have available.&lt;/p&gt;


	&lt;p&gt;Move along, nothing to see here.&lt;/p&gt;


&lt;/blockquote&gt; 

	&lt;p&gt;He didn&amp;#8217;t say &amp;#8220;it&amp;#8217;s not a good fit for this company&amp;#8221;, or &amp;#8220;yeah, we should look at in more depth when C++ is more pervasive&amp;#8221;.  He said &amp;#8220;it simply has no merit&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;This talk was &lt;em&gt;also&lt;/em&gt; very well received and again I can remember ranting to a colleage: &amp;#8220;What is &lt;em&gt;wrong&lt;/em&gt; with these guys?  Can&amp;#8217;t they see how much &lt;em&gt;simpler&lt;/em&gt; Object Orientation is?&amp;#8221;&lt;/p&gt;


	&lt;h2&gt;Week N&lt;/h2&gt;


	&lt;p&gt;A few years later the company did move to C++ for a completely new generation of their main product offering.&lt;/p&gt;


	&lt;p&gt;They attempted the &amp;#8220;big rewrite&amp;#8221;, expecting to recapture the features and lessons learned from years of work on a mature codebase and reproduce it in C++ (with a six month deadline).&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll never know whether they would have survived the schedule slippages and cost overruns on that project.  They bet the farm on Unix and almost overnight they lost their market, and all prospect for growth, to Microsoft Windows and Office.&lt;/p&gt;


	&lt;p&gt;By 2000 most of the company&amp;#8217;s assets had been sold off and the only mention of [Company Name] on the web was someone offering support contracts for the now-dead software.&lt;/p&gt;


	&lt;h2&gt;A Little Perspective a Lot of Years Later&lt;/h2&gt;


	&lt;p&gt;Aside from getting to witness first-hand the dangers of &amp;#8220;the big rewrite&amp;#8221; very early in my career, the most indelible marks were left by those talks back in 1992 and by the efforts to knock down C++ and &amp;#8220;Object Orientation&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;It took me a long time to understand the negative reaction.&lt;/p&gt;


	&lt;p&gt;It would be a disservice to say that the lead developer &amp;#8220;just didn&amp;#8217;t get it&amp;#8221;.  He was a gifted developer, able to slice through tricky problems like butter.  I admired his code for its clarity and succinctness and I read as much of it as I could.  When I did, I always learned something valuable.&lt;/p&gt;


	&lt;p&gt;So why did I, a complete newb with hardly any experience at all, see something beautiful in Object Orientation, while he could not?&lt;/p&gt;


	&lt;p&gt;Because I was a complete newb, with hardly any experience at all &amp;#8211; that&amp;#8217;s why.  Writing code was a struggle for me and I had to work hard to translate my mental-models into code.  Anything that made that easier was a godsend.&lt;/p&gt;


	&lt;p&gt;The lead developer, on the other hand, was fully tooled-up.  Expressing his intentions in code was simple and natural in K&amp;#38;R C.  He didn&amp;#8217;t &lt;em&gt;need&lt;/em&gt; any new language constructs or syntax to help him conceptualize solutions.  I can understand why he felt that C++ had nothing new to offer him.&lt;/p&gt;


	&lt;p&gt;But I think on the day he gave his talk he missed something important.  It&amp;#8217;s &lt;em&gt;all&lt;/em&gt; just syntax and language constructs.  Whether you &lt;em&gt;can&lt;/em&gt; do something with tool X or language Y doesn&amp;#8217;t address whether it&amp;#8217;s &lt;em&gt;natural&lt;/em&gt; to do so.&lt;/p&gt;


	&lt;p&gt;Saying &amp;#8220;there is nothing that C++ offers that well-written K&amp;#38;R C doesn&amp;#8217;t offer&amp;#8221; isn&amp;#8217;t the point.  Sure you can put pointers to functions in a struct, but how much more natural does it feel to just define a method for an object?  When you&amp;#8217;re staring at a blank screen and about to start coding, does the syntax implicitly nudge you in the right general direction?&lt;/p&gt;


	&lt;p&gt;If you were a beginner, would this new syntax seem natural to you?  Would it &lt;em&gt;speak&lt;/em&gt; to you?&lt;/p&gt;


	&lt;p&gt;Even with 15 years of hindsight I&amp;#8217;m not sure I know how I would have convinced him to disregard his hard-won K&amp;#38;R skills and techniques and to evaluate &amp;#8220;Object Orientation&amp;#8221; and C++ with a beginner&amp;#8217;s mind.&lt;/p&gt;


	&lt;p&gt;I think I struggle with it because he was right to reject C++ for the company at that time, but the reasons he gave (that you could achieve the same thing in K&amp;#38;R C) were wrong.&lt;/p&gt;


	&lt;h2&gt;So why the flashback today?&lt;/h2&gt;


	&lt;p&gt;Over on the Giant Robots blog there is a &lt;a href="http://giantrobots.thoughtbot.com/2008/1/7/why-bdd"&gt;discussion&lt;/a&gt; going on about &lt;span class="caps"&gt;BDD&lt;/span&gt;.  It&amp;#8217;s entitled &amp;#8220;Not Worth It&amp;#8221;.  The names may have changed but it&amp;#8217;s the same debate I witnessed in 1992.&lt;/p&gt;


	&lt;p&gt;And all I can think to do, when presented with guys that are fully tooled-up with &lt;span class="caps"&gt;TDD&lt;/span&gt; and Test::Unit skills and just see &lt;span class="caps"&gt;BDD&lt;/span&gt; and RSpec as (paraphrasing) &amp;#8220;just another syntax to achieve the same results&amp;#8221; is to say &amp;#8220;let me tell you about a couple of &amp;#8216;brown bag lunch&amp;#8217; talks I attended back when I first started out&amp;#8221;.&lt;/p&gt;</description>
      <pubDate>Mon,  7 Jan 2008 18:00:12 EST</pubDate>
      <guid>http://www.somethinglearned.com/articles/2008/01/07/giant-robots-giving-me-flashbacks</guid>
      <link>http://www.somethinglearned.com/articles/2008/01/07/giant-robots-giving-me-flashbacks</link>
      <category>code</category>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/36</trackback:ping>
    </item>
    <item>
      <title>What's new (and disappointing) in edge-rails</title>
      <description>&lt;p&gt;Recently a changeset &lt;a href="http://dev.rubyonrails.org/changeset/6951"&gt;(6591)&lt;/a&gt; made its way into Rails&amp;#8217; trunk.  A few people are blogging about &lt;a href="http://ryandaigle.com/articles/2007/6/6/what-s-new-in-edge-rails-nested-resource-restful-url-builder"&gt;how cool&lt;/a&gt; &lt;a href="http://tuples.us/2007/06/06/generic-url-builder-and-fixture-conveniences/"&gt;it is&lt;/a&gt; but I&amp;#8217;m going to blog about why it&amp;#8217;s bad.&lt;/p&gt;
&lt;h2&gt;So I tied an onion on my belt&amp;#8230;&lt;/h2&gt;


	&lt;p&gt;It actually all started with an earlier changeset &lt;a href="http://dev.rubyonrails.org/changeset/6588"&gt;(6588)&lt;/a&gt; which, in my opinion, made url helpers for nested resources just a twinge uglier.  What 6588 does is clean up syntax in routes.rb:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# Before 6588
map.resources :houses do |house|
  house.resources :walls
end

# After 6588   
map.resources :houses, :has_many =&amp;gt; :walls
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;No argument here &amp;#8211; that&amp;#8217;s a great idea.  However, such a change poses a problem with &lt;em&gt;polymorphic&lt;/em&gt; resources.  For the uninitiated, the term &amp;#8220;polymorphic resource&amp;#8221; generally refers to a resource that appears in multiple routes.&lt;/p&gt;


	&lt;p&gt;When you re-use the same resource in multiple routes you have to disambiguate the url helpers using a :name_prefix argument.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# Before 6588
map.resources :houses do |house|
  house.resources :walls, :name_prefix =&amp;gt; 'house_'
end

map.resources :outbuildings do |outbuilding|
  outbuilding.resources :walls, :name_prefix =&amp;gt; 'outbuilding_'
end
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;So now you can call either &lt;code&gt;house_wall_path(@house, @wall)&lt;/code&gt; or &lt;code&gt;outbuilding_wall_path(@outbuilding, @wall)&lt;/code&gt;.&lt;/p&gt;


	&lt;p&gt;Unfortunately there&amp;#8217;s no easy way to get the shiny new :has_many syntax in routes.rb while still expressing the name_prefix.  Changeset 6588 solves that by introducing some extra behavior.&lt;/p&gt;


	&lt;p&gt;Now, all your nested routes are automatically disambiguated with an implicit :name_prefix (unless you override it using the old-style block syntax and set :name_prefix to nil).  Leaving you with:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# After 6588   
map.resources :houses, :has_many =&amp;gt; :walls
map.resources :outbuildings, :has_many =&amp;gt; :walls
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Polymorphic goodness right?  No, as it happens.&lt;/p&gt;


	&lt;h2&gt;... as was the fashion at the time.&lt;/h2&gt;


	&lt;p&gt;The problem here is that auto-name_prefix is imposing a rather significant tax.&lt;/p&gt;


	&lt;p&gt;For now let&amp;#8217;s (conveniently) ignore the possibility of polymorphic resources.  After all, I know that I have &lt;em&gt;far&lt;/em&gt; fewer polymorphic resources in my routes.rb than I have simple plain-jane nested resources &amp;#8211; I suspect that&amp;#8217;s true for a lot of people.&lt;/p&gt;


	&lt;p&gt;Returning to the original example:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# Before 6588
map.resources :houses do |house|
  house.resources :walls
end
# wall_path(@house, @wall) #=&amp;gt; /houses/5/walls/6

# After 6588   
map.resources :houses, :has_many =&amp;gt; :walls
# house_wall_path(@house, @wall) #=&amp;gt; /houses/5/walls/6
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Did you see how the url helper for my wall just got longer?  Maybe I&amp;#8217;m the exception but I spend a lot more time typing out url helpers than I do typing out routes.  And because I have far more non-polymorphic resources than polymorphic ones, I don&amp;#8217;t &lt;em&gt;need&lt;/em&gt; all this automatic url helper disambiguation.&lt;/p&gt;


	&lt;p&gt;The implicit :name_prefix is &lt;strong&gt;just adding cruft&lt;/strong&gt; to plain old nested resources.&lt;/p&gt;


	&lt;h2&gt; Now, to take the ferry cost a nickel&amp;#8230;&lt;/h2&gt;


	&lt;p&gt;It&amp;#8217;s around about now that the &lt;a href="http://weblog.jamisbuck.org/2007/2/5/nesting-resources"&gt;resources should never be nested more than 1 level deep&lt;/a&gt; cargo-cult will see how I&amp;#8217;m passing both &lt;code&gt;@house&lt;/code&gt; &lt;em&gt;and&lt;/em&gt; &lt;code&gt;@wall&lt;/code&gt; in my arguments and start to get itchy trigger fingers.&lt;/p&gt;


	&lt;p&gt;Personally I think it&amp;#8217;s a shame that &amp;#8220;the amount of nesting you need is proportional to the ideas you&amp;#8217;re expressing&amp;#8221; isn&amp;#8217;t nearly as catchy as &amp;#8220;never more than 1 level deep&amp;#8221; but there you go.&lt;/p&gt;


	&lt;p&gt;But what&amp;#8217;s interesting is that the &amp;#8220;1-layer&amp;#8221; folks are doing something that looks like a polymorphic resource (the relationship being modeled isn&amp;#8217;t polymorphic, the controller is just being re-used).  Assume we just have :houses (and no :outbuildings):&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# 1-layer person says:
map.resources :houses, :has_many =&amp;gt; :walls
map.resources :walls, :has_many =&amp;gt; :windows
map.resources :windows

# instead of just:
map.resources :houses do |house|
  house.resources :walls, :has_many =&amp;gt; :windows
end
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;All of a sudden the url helpers for :walls and :windows need to be disambiguated.&lt;/p&gt;


	&lt;p&gt;From what I can tell, the benefits for the &amp;#8220;1-layer&amp;#8221; folks are a) shorter urls (regardless of how expressive they are?) and b) they avoid having to supply &amp;#8216;parents&amp;#8217; in the arguments for the deeply nested url helpers.&lt;/p&gt;


	&lt;p&gt;And while I can&amp;#8217;t help with short urls, some time ago I created a &lt;a href="http://agilewebdevelopment.com/plugins/resource_fu"&gt;plugin&lt;/a&gt; from which I created a &lt;a href="http://dev.rubyonrails.org/ticket/8469"&gt;patch&lt;/a&gt; that makes a deeply-nested &lt;code&gt;window_path(@house, @wall, @window)&lt;/code&gt; callable as &lt;code&gt;window_path(@window)&lt;/code&gt;.  No need to explicitly supply parents, they will be inferred if you choose not to supply them.&lt;/p&gt;


	&lt;p&gt;By the way, if you think the above &amp;#8220;1-layer&amp;#8221; style is just fine, consider that a logged-in user only has permission to view or edit the data for their associated houses.  So &lt;code&gt;User.has_many :houses&lt;/code&gt;.  What does the code look like in windows_controller.rb when ensuring the user should be looking at window 13 for example?&lt;/p&gt;


	&lt;p&gt;See, I&amp;#8217;m not blindly a &amp;#8220;1-layer&amp;#8221; guy so I&amp;#8217;d always have the house_id in the url &amp;#8211; and my controllers would just do a &lt;code&gt;current_user.houses.find(params[:house_id])&lt;/code&gt;.  Pretty straight-forward in my opinion.&lt;/p&gt;


	&lt;h2&gt;and in those days, nickels had pictures of bumblebees on &amp;#8216;em&amp;#8230;&lt;/h2&gt;


	&lt;p&gt;So back to yesterday&amp;#8217;s changeset (6591).  This changes the guts of Rails&amp;#8217; polymorphic_url() method in ways that, on the surface, look pretty cool.&lt;/p&gt;


	&lt;p&gt;Again, for the uninitiated, polymorphic_url() is a method that used to be part of the &lt;a href="http://dev.rubyonrails.org/browser/plugins/legacy/simply_helpful"&gt;simply_helpful&lt;/a&gt; plugin and has recently been factored into Rails&amp;#8217; trunk.&lt;/p&gt;


	&lt;p&gt;The reason why polymorphic_url() is cool is because it decides what url helper to invoke based on the class of the argument you pass &lt;em&gt;and&lt;/em&gt; in the case of ActiveRecord objects, whether the object is a new_record? or not.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;By the way, polymorphic_url() isn&amp;#8217;t really about polymorphic resources, it&amp;#8217;s more about &amp;#8220;I have an object, call the relevant url helper please&amp;#8221;.&lt;/em&gt;&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
polymorphic_url Something.new #=&amp;gt; somethings_path() #=&amp;gt; /somethings
polymorphic_url Something.find(:first) #=&amp;gt; something_path(your_first_record) #=&amp;gt; /somethings/1
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Layered on top of that behavior, are url_for() and form_for().  The form_for() helper is especially handy because it will either use :get or :post as the method for your form depending on whether the object is a new_record? or not.&lt;/p&gt;


	&lt;p&gt;Now you can use just &lt;em&gt;one&lt;/em&gt; form for your new and existing records.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
form_for Something.new #=&amp;gt; /somethings, :method =&amp;gt; :post
form_for Something.find(1) #=&amp;gt; /somethings/1, :method =&amp;gt; :put
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;All very cool.  What&amp;#8217;s the problem then?&lt;/p&gt;


	&lt;h2&gt;&amp;#8216;Give me five bees for a quarter,&amp;#8217; you&amp;#8217;d say.&lt;/h2&gt;


	&lt;p&gt;The problem is that deep in the bowels of polymorphic_url a new feature has arrived with changeset 6591.  Now you can pass an array to form_for (you couldn&amp;#8217;t before) to signify that you have a nested object.  Under the hood, polymorphic_url will call the correct url helper according to current Rails convention.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# routes.rb
map.resources :houses, :has_many =&amp;gt; :walls

# In a view:
form_for [@house, Wall.new] #=&amp;gt; house_walls_path(), :method =&amp;gt; :post
form_for [@house, Wall.find(1) #=&amp;gt; house_wall_path(1), :method =&amp;gt; :put
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;Again, in isolation that looks fine but note that it assumes the implicit :name_prefix values for my url helper names which, as I&amp;#8217;ve already stated, are just noise when you&amp;#8217;re not dealing with polymorphic resources.&lt;/p&gt;


	&lt;p&gt;So if I want to use form_for (specifically to have the benefit of the new_record? checking) while passing the parents as arguments, I have &lt;strong&gt;no choice but to use the name-prefixed form of url helpers&lt;/strong&gt; &amp;#8211; and that affects me whenever I just need a url.&lt;/p&gt;


	&lt;p&gt;Or I could take the stance that &lt;a href="http://tuples.us/2007/06/06/generic-url-builder-and-fixture-conveniences/"&gt;others&lt;/a&gt; are taking:&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;&amp;#8221;Yeah, url helpers sure got ugly because of the auto-name_prefix thing but now just call &lt;code&gt;url_for([@house, @wall])&lt;/code&gt; and it&amp;#8217;s &lt;strong&gt;much&lt;/strong&gt; clearer&amp;#8221;&lt;/em&gt;&lt;/p&gt;


	&lt;p&gt;Except it&amp;#8217;s not.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt; It&amp;#8217;s opaque.&lt;/li&gt;
		&lt;li&gt; And it&amp;#8217;s incomplete (how about a url to preview a new record?).  &lt;/li&gt;
		&lt;li&gt; And the interface has that leaky bolted-on feeling (wrapping your objects in an Array to overcome the method signature of url_for?  That&amp;#8217;s cheap).  &lt;/li&gt;
		&lt;li&gt; Did I mention opaque?&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Now where were we? Oh yeah&amp;#8230;&lt;/h2&gt;


	&lt;p&gt;What we have is a situation where truly-polymorphic resources (where the resource can have different parent types), of which I personally have comparatively few, and pseudo-polymorphic resources (as created by the &amp;#8220;1-layer&amp;#8221; folks), of which I have even fewer, are making life harder for non-polymorphic nested resources.&lt;/p&gt;


	&lt;p&gt;Perhaps I&amp;#8217;m in the minority but I believe &lt;strong&gt;the auto-name_prefix feature that was introduced in 6588 should be killed-off before any more leaky layers are added on top of it&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;And polymorphic resources should be treated as an edge-case.  It should be &amp;#8220;if you need it, put in the work&amp;#8221; rather than &amp;#8220;if you don&amp;#8217;t need it, put in the work&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Prior to changeset 6588, url helpers were clearer, simpler, and involved fewer keystrokes for the vast majority of cases.&lt;/p&gt;


	&lt;h2&gt;The important thing was that I had an onion on my belt&lt;/h2&gt;


	&lt;p&gt;Finally, if you &lt;em&gt;do&lt;/em&gt; need polymorphic resources, your clue is in the name.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;POLYMORPHIC&lt;/strong&gt;.  Using a monomorph (the same controller) to model something &lt;em&gt;polymorphic&lt;/em&gt; seems a little bone-headed don&amp;#8217;t you think?&lt;/p&gt;


	&lt;p&gt;The &lt;a href="http://sample.caboo.se/empty_rails_app/trunk/"&gt;caboose sample app&lt;/a&gt; (&lt;a href="http://blog.caboo.se/articles/2007/4/11/sample-rails-application"&gt;blog entry&lt;/a&gt;) has an example of how I believe you should model polymorphic resources.  &lt;a href="http://agilewebdevelopment.com/plugins/resource_fu"&gt;resource_fu&lt;/a&gt; wires it all together but it has moved on a bit since then (and still lacks full documentation) so the sample-app is a bit out-of-date.  When I get time I&amp;#8217;ll correct both of those issues.&lt;/p&gt;</description>
      <pubDate>Thu,  7 Jun 2007 01:24:56 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2007/06/07/whats-new-and-disappointing-in-edge-rails</guid>
      <link>http://www.somethinglearned.com/articles/2007/06/07/whats-new-and-disappointing-in-edge-rails</link>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/35</trackback:ping>
    </item>
    <item>
      <title>How To: Uncountable Names in RESTful Routes</title>
      <description>&lt;p&gt;A couple of times I&amp;#8217;ve noticed people saying that uncountable names (like sheep and fish) can&amp;#8217;t be used with resource routes in Rails.  Well, they can.&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# in config/routes.rb
map.resources :fish
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;In the above example there is a conflict between the generated url helpers for the &amp;#8216;fish&amp;#8217; collection and the generated url helpers for &lt;em&gt;members&lt;/em&gt; of the &amp;#8216;fish&amp;#8217; collection.  Because &amp;#8216;fish&amp;#8217; is uncountable, both are called &lt;code&gt;fish_path&lt;/code&gt; or &lt;code&gt;fish_url&lt;/code&gt;.  And because of the way routes and url helpers are created in a &lt;code&gt;map.resources&lt;/code&gt; call, the member url helpers override the collection ones.&lt;/p&gt;


	&lt;p&gt;So using the above example, calling &lt;code&gt;fish_path()&lt;/code&gt; raises an error like:&lt;/p&gt;


&lt;p&gt;&lt;code&gt;
ActionController::RoutingError: fish_url failed to generate from {:controller=&amp;gt;"fish", :action=&amp;gt;"show"} - you may have ambiguous routes, or you may need to supply additional parameters for this route.  content_url has the following required parameters: ["fish", :id] - are they all satisifed?
&lt;/code&gt;&lt;/p&gt;

	&lt;p&gt;Thankfully that&amp;#8217;s not the end of it. You just have to add a &lt;code&gt;:singular&lt;/code&gt; argument when defining your resources:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# in config/routes.rb
map.resources :fish, :singular =&amp;gt; :fish_instance

# in your code
fish_path() #=&amp;gt; /fish
new_fish_instance_path() #=&amp;gt; /fish/new
fish_instance_path(1) #=&amp;gt; /fish/1
edit_fish_instance_path(1) #=&amp;gt; /fish/1;edit
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;That&amp;#8217;s all.&lt;/p&gt;</description>
      <pubDate>Mon, 19 Mar 2007 00:03:23 EST</pubDate>
      <guid>http://www.somethinglearned.com/articles/2007/03/19/how-to-uncountable-names-in-restful-routes</guid>
      <link>http://www.somethinglearned.com/articles/2007/03/19/how-to-uncountable-names-in-restful-routes</link>
      <category>code</category>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/34</trackback:ping>
    </item>
    <item>
      <title>New Plugin: xls_fixtures</title>
      <description>&lt;p&gt;Here&amp;#8217;s a little something I whipped up that&amp;#8217;s proved useful.&lt;/p&gt;


	&lt;p&gt;Yaml is a pretty good format for storing fixture data but it can be a real pain to set up a bunch of fixtures with repeating or incrementing data.  There&amp;#8217;s a &lt;strong&gt;much&lt;/strong&gt; better tool out there for that &amp;#8211; Excel.&lt;/p&gt;


	&lt;p&gt;One way you can ease the pain of generating reams of fixture data is to build it all up in Excel and export your spreadsheets as csv files and tell Rails to use csv fixtures.  Unfortunately I couldn&amp;#8217;t find a way to have a moniker (my name for the non-indented line in your yaml fixtures) in the csv files so that I could refer to fixtures by name in my tests.&lt;/p&gt;


	&lt;p&gt;So what I&amp;#8217;ve done is to write a little plugin and rake task that converts xls files into yaml fixtures.  See:&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://svn.protocool.com/public/plugins/trunk/xls_fixtures/"&gt;http://svn.protocool.com/public/plugins/trunk/xls_fixtures/&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Note that it requires the &amp;#8216;parseexcel&amp;#8217; gem (as in &amp;#8220;gem install parseexcel&amp;#8221;) and you need to arrange your rows and columns as per the &lt;a href="http://svn.protocool.com/public/plugins/trunk/xls_fixtures/README"&gt;README&lt;/a&gt; file in the plugin.&lt;/p&gt;</description>
      <pubDate>Tue, 17 Oct 2006 13:54:46 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2006/10/17/new-plugin-xls_fixtures</guid>
      <link>http://www.somethinglearned.com/articles/2006/10/17/new-plugin-xls_fixtures</link>
      <category>code</category>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/33</trackback:ping>
    </item>
    <item>
      <title>Pastie: It's &amp;quot;italics good&amp;quot;</title>
      <description>&lt;p&gt;You come across interesting stuff by browsing &lt;a href="http://pastie.caboo.se"&gt;pastie&lt;/a&gt; but this tops them all.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://pastie.caboo.se/5900/wrap"&gt;http://pastie.caboo.se/5900/wrap&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 25 Jul 2006 13:25:42 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2006/07/25/pastie-its-italics-good</guid>
      <link>http://www.somethinglearned.com/articles/2006/07/25/pastie-its-italics-good</link>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/32</trackback:ping>
    </item>
    <item>
      <title>A little (more) syntactic sugar in Rails</title>
      <description>&lt;p&gt;This little extension to Ruby&amp;#8217;s Array class is making the rounds:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class Array
  def sum
    inject(0) { |m, v| m + v }
  end
end

# Use it thusly:
[1,2,3,4,5].sum # =&amp;gt; 15
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Nice.  But what if we want to sum a &lt;em&gt;member&lt;/em&gt; of each array element, such as the &amp;#8216;price_cents&amp;#8217; attribute on a bunch of ActiveRecord objects?&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
@order.line_items.collect {|x| x.price_cents}.sum
# or (my preference) using Symbol's to_proc method:
@order.line_items.collect(&amp;#38;:price_cents).sum
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Even with the sugar that Symbol#to_proc adds, it&amp;#8217;s just a bit&amp;#8230; well, &lt;em&gt;blech&lt;/em&gt;.  We can do better:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
class Array
  def sum
    if block_given?
      inject(0) { |m, v| m + yield(v) }
    else
      inject(0) { |m, v| m + v }
    end
  end
end

# Now we can say:
@order.line_items.sum(&amp;#38;:price_cents)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;That&amp;#8217;s just &lt;em&gt;so&lt;/em&gt; much clearer.&lt;/p&gt;


	&lt;p&gt;&lt;em&gt;Update: a recent &lt;a href="http://dev.rubyonrails.org/changeset/4489"&gt;changeset&lt;/a&gt; in the rails trunk adds a &amp;#8216;sum&amp;#8217; method to Enumerable.  It&amp;#8217;s different from what I present above in that it &lt;strong&gt;only&lt;/strong&gt; works with a block &amp;#8211; which is okay for me because that&amp;#8217;s my main usage pattern anyhow.&lt;/em&gt;&lt;/p&gt;</description>
      <pubDate>Mon, 12 Jun 2006 13:48:56 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2006/06/12/a-little-more-syntactic-sugar-in-rails</guid>
      <link>http://www.somethinglearned.com/articles/2006/06/12/a-little-more-syntactic-sugar-in-rails</link>
      <category>code</category>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/31</trackback:ping>
    </item>
    <item>
      <title>A Rails tale of caution: functional tests hanging with controllers in subdirectories</title>
      <description>&lt;p&gt;This afternoon I was hit by a real headscratcher &amp;#8211; documented here for future googlers looking for information on: functional tests hanging controllers subdirectories :-)&lt;/p&gt;


	&lt;p&gt;I added in some tests for controllers that were in a subdirectory (as in &amp;#8220;&lt;code&gt;./script/generate controller boo/hoo&lt;/code&gt;&amp;#8220;) and suddenly rake started hanging.&lt;/p&gt;


	&lt;p&gt;I could run individual functional tests just fine but as a suite &amp;#8211; forget it.&lt;/p&gt;


	&lt;p&gt;The source of the problem turned out to be twofold:&lt;/p&gt;


	&lt;ol&gt;
	&lt;li&gt;in test_helper.rb we alias the &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;post&lt;/code&gt; test methods so that we can optionally capture all of our output and run it through a validator.&lt;/li&gt;
		&lt;li&gt;the require line that ./script/generate creates for loading test_helper.rb in your functional tests is &lt;em&gt;relative&lt;/em&gt; to the current file&amp;#8217;s directory.  For functional tests in subdirectories you get a &lt;code&gt;require&lt;/code&gt; argument ending with &amp;#8221;/../../test_helper&amp;#8221; rather than the one ending with &amp;#8221;/../test_helper&amp;#8221;  as you do in top-level functional tests.&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Even though those two different require lines point to the same file, from &lt;em&gt;require&amp;#8217;s&lt;/em&gt; perspective they are different &amp;#8211; so the file is loaded twice.&lt;/p&gt;


	&lt;p&gt;And that&amp;#8217;s a big no-no if you are doing a simple method alias &lt;strong&gt;without checks against doing it twice&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;The bulletproof solution is to have tests use &lt;code&gt;File.expand_path()&lt;/code&gt; on the argument to &lt;code&gt;require&lt;/code&gt;.  But if the generators keep spitting it out as they do now it&amp;#8217;s one of those &amp;#8220;pushing water uphill&amp;#8221; situations. I smell a patch.&lt;/p&gt;


	&lt;p&gt;For now, I&amp;#8217;m just wrapping my &lt;code&gt;alias&lt;/code&gt; calls with a check of &lt;code&gt;self.instance_methods&lt;/code&gt; to make sure the alias hasn&amp;#8217;t already been done.&lt;/p&gt;</description>
      <pubDate>Tue, 30 May 2006 19:27:05 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2006/05/30/a-rails-tale-of-caution-functional-tests-hanging-with-controllers-in-subdirectories</guid>
      <link>http://www.somethinglearned.com/articles/2006/05/30/a-rails-tale-of-caution-functional-tests-hanging-with-controllers-in-subdirectories</link>
      <category>code</category>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/30</trackback:ping>
    </item>
    <item>
      <title>Living under a rock?  Google and Sketchup</title>
      <description>&lt;p&gt;A few years back, while I was building my house, I downloaded a demo copy of &lt;a href="http://sketchup.google.com/"&gt;Sketchup&lt;/a&gt; to help visualize how everything would look.  It&amp;#8217;s a &lt;strong&gt;fantastic&lt;/strong&gt; tool for 3D design, one of those rare pieces of software that just makes sense.&lt;/p&gt;


	&lt;p&gt;Unfortunately it&amp;#8217;s also software that costs about $500 &lt;span class="caps"&gt;USD&lt;/span&gt; and as much as I wanted to, I simply couldn&amp;#8217;t justify the expense.  My love affair with Sketchup was doomed to be just a few short weeks as the demo period quickly slipped away.&lt;/p&gt;


	&lt;p&gt;Sketchup did leave me with a legacy though: Ruby.  It ships with a ruby interpreter and has hooks to extend the software with Ruby scripts.  Had I not seen the Ruby/Sketchup integration I probably wouldn&amp;#8217;t have given Rails a second look when I stumbled across it a year and a half (gosh!) ago.&lt;/p&gt;


	&lt;p&gt;Okay, that&amp;#8217;s enough nostalgia.  The real point here isn&amp;#8217;t whether I owe a debt of gratitude to a 3D modeling program for more than a year of fun, full-time work with Rails&amp;#8230;&lt;/p&gt;


	&lt;p&gt;The real point here is that Google bought Sketchup &lt;strong&gt;and&lt;/strong&gt; they are releasing cut-down free versions.  I think that&amp;#8217;s pretty big news and I have absolutely no idea how I missed it.&lt;/p&gt;


	&lt;p&gt;They&amp;#8217;ve already released the &lt;a href="http://sketchup.google.com/"&gt;free version&lt;/a&gt; for PC and apparently a free version for &lt;span class="caps"&gt;OS X&lt;/span&gt; is in the works as well.&lt;/p&gt;


	&lt;p&gt;I am &lt;em&gt;so&lt;/em&gt; chuffed about this.  It&amp;#8217;s going to make designing my kids&amp;#8217; backyard playstructure a breeze.&lt;/p&gt;</description>
      <pubDate>Sun, 28 May 2006 21:16:40 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2006/05/28/living-under-a-rock-google-and-sketchup</guid>
      <link>http://www.somethinglearned.com/articles/2006/05/28/living-under-a-rock-google-and-sketchup</link>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/29</trackback:ping>
    </item>
    <item>
      <title>Snippet: using 'inherited' to set filters in controllers</title>
      <description>&lt;p&gt;One of my apps has a set of controllers in an &amp;#8217;/admin&amp;#8217; directory.  They all must have a &lt;code&gt;:login_required&lt;/code&gt; before_filter and they all must define an &lt;code&gt;authorized?&lt;/code&gt; method that checks if the current user is an administrator.&lt;/p&gt;


	&lt;p&gt;For a couple of reasons the idea of having a special &amp;#8220;AdminController&amp;#8221; which everything under &amp;#8217;/admin&amp;#8217; would inherit from (and that set up the filter and authorized? method) kind of irked me.&lt;/p&gt;


	&lt;p&gt;First, there was the name clash &amp;#8211; AdminController becomes &amp;#8216;admin&amp;#8217; in routes and that clashes with my directory called &amp;#8216;admin&amp;#8217;, so I&amp;#8217;d have to choose a name like &amp;#8220;AdminBaseController&amp;#8221; or some-such.  &lt;em&gt;Blech&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Second, I just didn&amp;#8217;t like the extra file for the base controller.  Call me picky, I can take it.&lt;/p&gt;


	&lt;p&gt;What I wanted was a way to say &amp;#8220;if the controller is in the /admin directory then it needs this filter and this method&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Class#inherited to the rescue.  Here&amp;#8217;s what I put in &lt;code&gt;/app/controllers/application.rb&lt;/code&gt;:&lt;/p&gt;


&lt;code&gt;&lt;pre&gt;
# For all controllers in the 'Admin' namespace we set
# the login_required before_filter and define an authorized?
# method that checks user.is_administrator? 
def self.inherited(subclass)
  # call super first - otherwise any before_filters we add are lost
  super
  if subclass.name.split('::').first == 'Admin'
    subclass.before_filter :login_required
    subclass.send(:define_method, :authorized?, Proc.new {|user| user.is_administrator?})
    subclass.send(:protected, :authorized?)
  end
end
&lt;/pre&gt;&lt;/code&gt;

	&lt;p&gt;This is fine for my present needs.  If controllers under /admin start to need any more shared behavior I&amp;#8217;ll just bite the bullet and do the AdminBaseController thing &amp;#8211; but for now this is clean and works.&lt;/p&gt;</description>
      <pubDate>Fri, 26 May 2006 18:51:37 EDT</pubDate>
      <guid>http://www.somethinglearned.com/articles/2006/05/26/snippet-using-inherited-to-set-filters-in-controllers</guid>
      <link>http://www.somethinglearned.com/articles/2006/05/26/snippet-using-inherited-to-set-filters-in-controllers</link>
      <category>code</category>
      <trackback:ping>http://www.somethinglearned.com/articles/trackback/28</trackback:ping>
    </item>
  </channel>
</rss>
