<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" xml:lang="en-US">
  <title>GIANT ROBOTS SMASHING INTO OTHER GIANT ROBOTS - Home</title>
  <id>tag:giantrobots.thoughtbot.com,2009:mephisto/</id>
  <generator version="0.8.0" uri="http://mephistoblog.com">Mephisto Drax</generator>
  
  <link href="http://giantrobots.thoughtbot.com/" rel="alternate" type="text/html" />
  <updated>2009-06-25T15:51:10Z</updated>
  <link rel="self" href="http://feeds.feedburner.com/GiantRobotsSmashingIntoOtherGiantRobots" type="application/atom+xml" /><feedburner:browserFriendly>This is an XML content feed. It is intended to be viewed in a newsreader or syndicated to another site, subject to copyright and fair use.</feedburner:browserFriendly><entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Nick Quaranto</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-06-25:8694</id>
    <published>2009-06-25T15:49:00Z</published>
    <updated>2009-06-25T15:51:10Z</updated>
    <category term="Development" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/9Fb4Y6hTjDU/internbot-chronicles-5-training-reflections" rel="alternate" type="text/html" />
    <title>Internbot Chronicles #5: Training Reflections</title>
<content type="html">
            &lt;p&gt;Last week I sat in on the &lt;a href="http://thoughtbot.com/services/training"&gt;Training&lt;/a&gt; class we held here at the Boston office. I haven’t considered Ruby or Rails from the point of a greenhorn in a few years, and helping the students learn about both opened my eyes quite a bit to some aspects of our language and framework of choice here at Thoughtbot.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.flickr.com/photos/jaxxon/3157745377/"&gt;&lt;img src="http://farm4.static.flickr.com/3284/3157745377_94d7d66268_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;h2&gt;Ruby is natural, not simple.&lt;/h2&gt;


	&lt;p&gt;This is paraphrased one of my now &lt;a href="http://www.ruby-lang.org/en/about/"&gt;favorite Matz quotes&lt;/a&gt;. Watching others learn about Ruby for the first time was a lot of fun, because usually they were astounded to find out that what they used to do was just so…simple. Of course, under the hood, Ruby is exactly the opposite, but that’s the beauty of it. &lt;a href="http://hanselman.com"&gt;Scott Hanselman&lt;/a&gt; explains it best by &lt;a href="http://www.hanselman.com/blog/ProgrammerIntentOrWhatYoureNotGettingAboutRubyAndWhyItsTheTits.aspx"&gt;showing a great example&lt;/a&gt; of using Ruby DSLs such as &lt;code&gt;20.minutes.ago&lt;/code&gt; instead of the more verbose Java equivalent &lt;code&gt;new Date(new Date().getTime() - 20 * 60 * 1000)&lt;/code&gt;. He ends up concluding:&lt;/p&gt;


&lt;blockquote&gt;That was a perfect way to describe &lt;em&gt;__&lt;/em&gt;, and there’s no ambiguity.&lt;/blockquote&gt;

	&lt;p&gt;This aspect of Ruby has stuck with me since I first tried to dive through the &lt;a href="http://whytheluckystiff.net/ruby/pickaxe/"&gt;Pickaxe&lt;/a&gt;. However, it didn’t really work out that nicely: I learned Rails first, and Ruby along the way. Having a basic understanding of Ruby, especially with how blocks and the &lt;code&gt;yield&lt;/code&gt; keyword works can go a long way. The best part is that given a bottom-up approach, it’s easy to see how the expressiveness of Ruby fits perfectly into Rails.&lt;/p&gt;


	&lt;h2&gt;Rails isn’t full of black magic.&lt;/h2&gt;


	&lt;p&gt;Without a good understanding of Ruby, it’s easy to think that this is the case. ActiveRecord can seem like a bag of tricks dumped on top of your precious database, and don’t even get me started with some of the ActionView helpers. One of the best parts of the training was when we hooked up a form, and used &lt;code&gt;error_messages_for&lt;/code&gt; to show the validation errors. Watching the students’ eyes light up with understanding how that all came together was fantastic, but it did seem like “witchcraft” to a few.&lt;/p&gt;


	&lt;p&gt;Granted, there is a lot of metaprogramming going on in Rails, but I feel the more Ruby one understands, the less “magical” it seems. Learning Ruby first is the best way to go, especially since it allows one to dive easily into the latest and greatest projects, such as &lt;a href="http://cukes.info"&gt;Cucumber&lt;/a&gt; or &lt;a href="http://www.sinatrarb.com"&gt;Sinatra&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Someone’s already done this before.&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Convention_over_Configuration"&gt;Convention over configuration&lt;/a&gt; here is key: not having to understand some cryptic &lt;span class="caps"&gt;XML&lt;/span&gt; file to set up your database or the application as a whole is a huge win. Using &lt;a href="http://guides.rails.info/migrations.html"&gt;pure Ruby for migrations&lt;/a&gt; is just one example of how Rails makes web development easier. Staying on the “golden path” is a huge part of Rails, and you can usually bet that someone has solved the problem you’re facing before. Looking for the solution inside the framework or outside for a well-tested and maintained plugin before you steam ahead with your own implementation is always a smart idea. I definitely have been to blame for this: I began writing my own Prototype implementation of &lt;code&gt;periodically_call_remote&lt;/code&gt; before getting called out on it.&lt;/p&gt;


	&lt;p&gt;One of the big lessons that I took away from training was that we really do depend on the community for most of our tools: &lt;a href="http://capify.org"&gt;Capistrano&lt;/a&gt;, &lt;a href="http://git-scm.org"&gt;Git&lt;/a&gt;, &lt;a href="http://prawn.majesticseacreature.com/"&gt;Prawn&lt;/a&gt; ...the list goes on and on. If you’re not looking to community for your solutions in the Ruby world or are not aware of what’s available, &lt;strong&gt;you’re missing out.&lt;/strong&gt; Keeping in touch with what’s new is tough, but luckily there’s &lt;a href="http://planetrubyonrails.com"&gt;a&lt;/a&gt; &lt;a href="http://rubyflow.com"&gt;few&lt;/a&gt; &lt;a href="http://rubyinside.com"&gt;sites&lt;/a&gt; that make it really easy for you to do so.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.flickr.com/photos/fornal/391257935/"&gt;&lt;img src="http://farm1.static.flickr.com/141/391257935_b95d62b8ff_m.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Overall, training was a lot of fun. Over the course of three days we went from playing around with Ruby objects in irb, whipping together a simple Rails site, to deploying it live on &lt;a href="http://heroku.com"&gt;Heroku&lt;/a&gt;. Going back to the basics was definitely eye opening, and it was a good reminder that I should trudge through the &lt;a href="http://www.pragprog.com/titles/ruby3/programming-ruby-1-9"&gt;Pickaxe for Ruby 1.9&lt;/a&gt; as soon as possible.&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/6/25/internbot-chronicles-5-training-reflections</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Chad Pytel</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-06-11:8586</id>
    <published>2009-06-11T20:27:00Z</published>
    <updated>2009-06-11T22:56:01Z</updated>
    <category term="Business" />
    <category term="Design" />
    <category term="Development" />
    <category term="designer" />
    <category term="developer" />
    <category term="hiring" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/hn2_yJdipVs/we-ve-got-several-positions-open-developer-designer-and-intern" rel="alternate" type="text/html" />
    <title>We've got several positions open (Developers, Designers, and Intern)</title>
<content type="html">
            &lt;p&gt;I just wanted to take a moment to remind everyone that we still have several positions open at thoughtbot.&lt;/p&gt;


	&lt;p&gt;We’re looking to hire up to &lt;strong&gt;2 web designers&lt;/strong&gt;, preferably one in Boston and one in &lt;span class="caps"&gt;NYC&lt;/span&gt;, and up to &lt;strong&gt;3 developers&lt;/strong&gt; in Boston.&lt;/p&gt;


	&lt;p&gt;Also, this summer, we’ve had Nick Quaranto in as &lt;strong&gt;a development intern&lt;/strong&gt;, and he’s worked out so well that we’d like to get another, so we’re opening the internship position back up to find another.&lt;/p&gt;


	&lt;p&gt;All positions include relocation expenses as part of the benefits.  You can read more about these positions on our &lt;a href="http://www.thoughtbot.com/jobs"&gt;jobs page&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Our team works in a relaxed and educational environment. We use the latest web development technologies, and embrace both agile development methodologies and a “getting real” project philosophy. We limit our work weeks to 40 hours, stock the fridge with free drinks, and provide lunch on Fridays.&lt;/p&gt;


	&lt;p&gt;We believe in goal-driven business development (we want to understand what’s valuable to clients before we begin), design-driven product development (we want to know what a product will look like and how it will work before we start building it) and test-driven software development (we want to ensure ongoing quality and a successful post-launch existence for the applications we build).&lt;/p&gt;


	&lt;p&gt;If you are interested, contact us at &lt;a href="mailto:resumes@thoughtbot.com"&gt;resumes@thoughtbot.com&lt;/a&gt;.&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/6/11/we-ve-got-several-positions-open-developer-designer-and-intern</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Dan Croak</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-06-06:8537</id>
    <published>2009-06-06T19:00:00Z</published>
    <updated>2009-06-06T19:02:57Z</updated>
    <category term="apartment" />
    <category term="boston" />
    <category term="housing" />
    <category term="neighborhood" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/NigDR7r4fCw/boston-neighborhood-guide-for-tasteful-rubyists-designers" rel="alternate" type="text/html" />
    <title>Boston neighborhood guide for tasteful Rubyists &amp; designers</title>
<content type="html">
            &lt;p&gt;I have a friend from another city who is considering a Ruby job in Boston. He asked me for advice on places to live.&lt;/p&gt;


	&lt;p&gt;Since we’re currently in the midst of &lt;a href="http://thoughtbot.com/jobs"&gt;hiring designers &amp; developers&lt;/a&gt; &amp; many candidates have been from other areas (we require that they move to Boston or New York), I thought I’d share publicly.&lt;/p&gt;


	&lt;h2&gt;Opinions&lt;/h2&gt;


	&lt;p&gt;If you’re a Rubyist or a designer, you’ve already got taste. The following neighborhoods are what I personally consider the nicest, most intellectually stimulating, aesthetically pleasing, or funkiest neighborhoods.&lt;/p&gt;


	&lt;p&gt;This is by no means comprehensive but that’s partly the point. Moving is stressful &amp; keeping options limited lightens the mental burden.&lt;/p&gt;


	&lt;h2&gt;Cost of living&lt;/h2&gt;


	&lt;p&gt;Boston rent is not for the faint of heart. Expect to pay between $750-$1,250/month for a clean apartment close to Boston. You should be able to knock it down to $500/month if you share a bedroom with someone or live in Jamaica Plain.&lt;/p&gt;


	&lt;p&gt;However, average salary, and more importantly, the quality of life are also high.&lt;/p&gt;


	&lt;h2&gt;Cambridge&lt;/h2&gt;


	&lt;p&gt;I’ve mostly lived in Cambridge over the last 5 years so let’s start here. The &lt;a href="http://en.wikipedia.org/wiki/Cambridge,_Massachusetts"&gt;Wikipedia entry&lt;/a&gt; hits the high points of Cambridge culture: Harvard University, &lt;span class="caps"&gt;MIT&lt;/span&gt;, the Charles River, &amp; &lt;a href="http://www.mbta.com/schedules_and_maps/subway/lines/?route=RED"&gt;The Red Line&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The blue line encompasses the sections of Cambridge I’d recommend: most of Cambridge except areas that are more industrial or North Cambridge, which is just a little too far from downtown Boston for my tastes.&lt;/p&gt;


&amp;lt;iframe src="http://quikmaps.com/ext2/105975?t=1&amp;amp;#38;ln=0&amp;amp;#38;sn=1&amp;amp;#38;zb=0&amp;amp;#38;d=1&amp;amp;#38;o=0&amp;amp;#38;lat=42.3701476&amp;amp;#38;lng=-71.1045456&amp;amp;#38;zl=13&amp;amp;#38;mt=2" height="400" width="550"&gt;&amp;lt;/iframe&gt;

	&lt;p&gt;I put three pushpins in Boston for reference: Fenway Park, the Prudential Center, &amp; Park Street at Boston Common (&lt;a href="http://giantrobots.thoughtbot.com/assets/2009/6/6/Picture_3_tiny.png?1244311562"&gt;where the thoughtbot office is located&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;If, like my friend, you’re not working downtown, but instead in Watertown, Waltham, Somerville, Medford, or Charlestown, I’d strongly recommend Cambridge.&lt;/p&gt;


	&lt;h2&gt;Brookline&lt;/h2&gt;


	&lt;p&gt;Again, the &lt;a href="http://en.wikipedia.org/wiki/Brookline,_Massachusetts"&gt;Wikipedia entry&lt;/a&gt; will give you the best overview of the town &amp; it’s culture: John F. Kennedy, The Country Club, &amp; &lt;a href="http://www.mbta.com/schedules_and_maps/subway/lines/?route=GREEN"&gt;The Green Line&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;This is an area I’d recommend for people with kids. Quiet, safe, &amp; great schools. It’s close to Waltham, Watertown, &amp; the &lt;a href="http://en.wikipedia.org/wiki/Massachusetts_Turnpike"&gt;Mass Pike&lt;/a&gt; if you’re working out along Route 128. It’s also extremely convenient if you’re working in the Longwood area (I believe there are a number of hospitals &amp; universities over there &lt;a href="http://bostonrb.org/#jobs"&gt;hiring Rubyists&lt;/a&gt;).&lt;/p&gt;


	&lt;p&gt;Within Brookline, Coolidge Corner &amp; Washington Square are the two areas I would focus on. They’re both right on the Green Line along Beacon Street &amp; have plenty of things worth walking to.&lt;/p&gt;


&amp;lt;iframe src="http://quikmaps.com/ext2/105977?t=1&amp;amp;#38;ln=0&amp;amp;#38;sn=1&amp;amp;#38;zb=0&amp;amp;#38;d=1&amp;amp;#38;o=0&amp;amp;#38;lat=42.34075055&amp;amp;#38;lng=-71.12754819999999&amp;amp;#38;zl=14&amp;amp;#38;mt=2" height="400" width="550"&gt;&amp;lt;/iframe&gt;

	&lt;h2&gt;Jamaica Plain&lt;/h2&gt;


	&lt;p&gt;Wikipedia calls Jamaica Plain &lt;a href="http://en.wikipedia.org/wiki/Jamaica_Plain,_Massachusetts#Present_day"&gt;The Eden of America&lt;/a&gt;. I can see that.&lt;/p&gt;


	&lt;p&gt;This is where you want to be if you’re a park lover or a real artist. The population is extremely diverse demographically. The &lt;a href="http://www.milkywayjp.com/"&gt;Milky Way Lounge&lt;/a&gt; (Latin dance nights), &lt;a href="http://www.jplicks.com"&gt;JP Licks&lt;/a&gt; (ice cream), &amp; &lt;a href="http://www.doyles-cafe.com/history.aspx"&gt;Doyle’s Cafe&lt;/a&gt; (oldest Irish pub in Boston, longtime evening hangout for the city’s Irish politicians) are iconic institutions.&lt;/p&gt;


	&lt;p&gt;The area I’d recommend is bounded by the &lt;a href="http://www.mbta.com/schedules_and_maps/subway/lines/?route=ORANGE"&gt;Orange Line&lt;/a&gt; on the right, the ponds on the left, and is split by Centre Street, which is filled with attractive cafes, galleries, restaurants &amp; shops.&lt;/p&gt;


&amp;lt;iframe src="http://quikmaps.com/ext2/105995?t=1&amp;amp;#38;ln=0&amp;amp;#38;sn=1&amp;amp;#38;zb=0&amp;amp;#38;d=1&amp;amp;#38;o=0&amp;amp;#38;lat=42.31478155&amp;amp;#38;lng=-71.1131501&amp;amp;#38;zl=14&amp;amp;#38;mt=2" height="400" width="550"&gt;&amp;lt;/iframe&gt;

	&lt;h2&gt;South End&lt;/h2&gt;


	&lt;p&gt;Scan through the &lt;a href="http://en.wikipedia.org/wiki/South_End"&gt;Wikipedia entry&lt;/a&gt; then take a walk through the area. If you’re not touched by the signature brick architecture of Boston that is prevalent in the South End, you have no heart. You’re probably a vampire. Might want to get that checked out.&lt;/p&gt;


	&lt;p&gt;The South End is known as a gay &amp; artistic neighborhood. Tremont Street may have the greatest concentration of “Saturday night date restaurants” in the city. Unbelievable food over there. Lots of theaters, lots of music, lots of visual arts.&lt;/p&gt;


	&lt;p&gt;I’ve bounded the South End by some major streets.&lt;/p&gt;


&amp;lt;iframe src="http://quikmaps.com/ext2/105996?t=1&amp;amp;#38;ln=0&amp;amp;#38;sn=1&amp;amp;#38;zb=0&amp;amp;#38;d=1&amp;amp;#38;o=0&amp;amp;#38;lat=42.3423526&amp;amp;#38;lng=-71.07392549999999&amp;amp;#38;zl=15&amp;amp;#38;mt=2" height="400" width="550"&gt;&amp;lt;/iframe&gt;

	&lt;p&gt;It’s a tricking balancing act of trying to live in the South End, however. The closer you are to Copley, the closer you are to some of the highest rent areas of Boston. The closer to Washington Street, the further you are from all subway lines &amp; the closer you are to some higher crime areas. Like any city, however, often the best places to live are on the edge of gentrification of former combat zones.&lt;/p&gt;


	&lt;h2&gt;For the venture capitalists…&lt;/h2&gt;


	&lt;p&gt;It wouldn’t be tour through Boston’s neighborhoods if I didn’t point out the &lt;a href="http://en.wikipedia.org/wiki/Back_Bay,_Boston,_Massachusetts"&gt;Back Bay&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Beacon_Hill,_Boston,_Massachusetts"&gt;Beacon Hill&lt;/a&gt;, &amp; the &lt;a href="http://is.gd/QBEo"&gt;North End&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;These are all awesome neighborhoods that are out of the price range of most individuals unless you’re the kind of person who likes to fund Twitter or knock home runs out of &lt;a href="http://3.media.tumblr.com/1TEAMALpso95sskn0LdpcSH5o1_500.jpg"&gt;Fenway Park&lt;/a&gt;.&lt;/p&gt;


&amp;lt;iframe src="http://quikmaps.com/ext2/105998?t=1&amp;amp;#38;ln=0&amp;amp;#38;sn=1&amp;amp;#38;zb=0&amp;amp;#38;d=1&amp;amp;#38;o=0&amp;amp;#38;lat=42.3581626&amp;amp;#38;lng=-71.07210160000001&amp;amp;#38;zl=14&amp;amp;#38;mt=2" height="400" width="500"&gt;&amp;lt;/iframe&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/6/6/boston-neighborhood-guide-for-tasteful-rubyists-designers</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Nick Quaranto</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-06-04:8520</id>
    <published>2009-06-04T17:28:00Z</published>
    <updated>2009-06-04T17:45:58Z</updated>
    <category term="Development" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/nqnp3i1pomM/documentation-demolition-derby" rel="alternate" type="text/html" />
    <title>Documentation Demolition Derby</title>
<content type="html">
            &lt;p&gt;&amp;lt;object height="344" width="425"&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;embed src="http://www.youtube.com/v/PPkJCZg1T14&amp;amp;#38;hl=en&amp;amp;#38;fs=1&amp;amp;#38;rel=0" height="344" width="425"&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;/p&gt;


	&lt;p&gt;Who doesn’t love cars crashing into other cars? And freshly generated documentation? Well, now you can get both. Or maybe just documentation. We’ve moved our open source projects’ documentation onto &lt;a href="http://rdoc.info"&gt;RDoc.info&lt;/a&gt;, which uses &lt;a href="http://wiki.github.com/lsegal/yard"&gt;&lt;span class="caps"&gt;YARD&lt;/span&gt;&lt;/a&gt; and some GitHub &lt;a href="http://github.com/guides/post-receive-hooks"&gt;post-receive hooks&lt;/a&gt; to make sure it’s always up to date. Update your bookmarks, delicious links, cheat sheets, wikis, what have you:&lt;/p&gt;


&lt;table&gt;&lt;tr&gt;
&lt;td&gt;
&lt;a href="http://rdoc.info/projects/thoughtbot/shoulda"&gt;&lt;img src="http://thoughtbot.com/assets/icon-shoulda.png" /&gt;&lt;/a&gt;
&lt;h3&gt;&lt;a href="http://rdoc.info/projects/thoughtbot/shoulda"&gt;Shoulda&lt;/a&gt;&lt;/h3&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://rdoc.info/projects/thoughtbot/paperclip"&gt;&lt;img src="http://thoughtbot.com/assets/icon-paperclip.png" /&gt;&lt;/a&gt;
&lt;h3&gt;&lt;a href="http://rdoc.info/projects/thoughtbot/paperclip"&gt;Paperclip&lt;/a&gt;&lt;/h3&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;a href="http://rdoc.info/projects/thoughtbot/factory_girl"&gt;&lt;img src="http://thoughtbot.com/assets/icon-factorygirl.png" /&gt;&lt;/a&gt;
&lt;h3&gt;&lt;a href="http://rdoc.info/projects/thoughtbot/factory_girl"&gt;Factory Girl&lt;/a&gt;&lt;/h3&gt;
&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/6/4/documentation-demolition-derby</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Nick Quaranto</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-05-29:8462</id>
    <published>2009-05-29T16:12:00Z</published>
    <updated>2009-05-29T16:15:35Z</updated>
    <category term="Development" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/YAD0dP_Vrgc/internbot-chronicles-4" rel="alternate" type="text/html" />
    <title>Internbot Chronicles #4: CI &amp; Test Metrics</title>
<content type="html">
            &lt;p&gt;Inspired by some of the great talks at &lt;a href="http://giantrobots.thoughtbot.com/2009/5/12/railsconf-2009-wrapup"&gt;RailsConf 2009&lt;/a&gt; such as &lt;a href="http://litanyagainstfear.com/blog/2009/05/07/railsconf-2009-automated-code-quality-checking-in-ruby-and-rails/"&gt;Automated Code Quality Checking in Ruby on Rails&lt;/a&gt; along with &lt;a href="http://onrails.org/articles/2009/05/07/railsconf-2009-day-two"&gt;Using metric_fu to Make Your Rails Code Better&lt;/a&gt;, this Internbot was recently tasked with getting a similar system working for the open source projects and Rails client sites that live in the Thoughtbot ecosystem.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://ci.thoughtbot.com"&gt;&lt;img src="http://farm4.static.flickr.com/3297/3575434187_346d8f6068.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The first step of this process was to get a new CI server up an running. Thoughtbot was using &lt;a href="http://cruisecontrolrb.thoughtworks.com"&gt;CruiseControl.rb&lt;/a&gt; and &lt;a href="http://runcoderun.com/"&gt;RunCodeRun&lt;/a&gt; previously, but both had fallen out of use recently. I had some experience with setting up &lt;a href="http://integrityapp.com"&gt;Integrity&lt;/a&gt;, which is a much easier to use system. Adding a new project is dead simple: plug in your project’s Git &lt;span class="caps"&gt;URL&lt;/span&gt;, give it a build script to run (usually just &lt;code&gt;rake&lt;/code&gt;) and boom, you’ve got CI. Integrity also supports &lt;a href="http://github.com/guides/post-receive-hooks"&gt;post-receive hooks&lt;/a&gt;, so when we push commits GitHub tells Integrity to grab the latest changes and get testing. We also make use of the &lt;a href="http://github.com/integrity/integrity-campfire/tree"&gt;Campfire hook&lt;/a&gt; to let us know the results of the build.&lt;/p&gt;


	&lt;p&gt;It was easy to get Integrity itself running, but getting the tests passing for all of our projects was no simple task. Here’s some of the gotchas that I ran into that might help you out if you’re putting together your own CI server:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Make sure your Rails apps’ database tables exist. In hindsight, simply running &lt;code&gt;rake db:create:all&lt;/code&gt; would have done the trick.&lt;/li&gt;
		&lt;li&gt;Use a Linux distro with an up-to-date version of Ruby that’s easily available. We settled on Ubuntu 8.10 with Ruby 1.8.7 patchlevel 72.&lt;/li&gt;
		&lt;li&gt;The build script can take &lt;strong&gt;any&lt;/strong&gt; system command, so use it for setting up your test environment if necessary.&lt;/li&gt;
		&lt;li&gt;Builds don’t run in the background, so switch them to a different port if you want to be able to view your projects while builds are running.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Check out our build server at &lt;a href="http://ci.thoughtbot.com"&gt;http://ci.thoughtbot.com&lt;/a&gt; if you want to see the status of our projects.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://metrics.thoughtbot.com"&gt;&lt;img src="http://farm4.static.flickr.com/3652/3576240372_fd70812dd4.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Next up was getting some metrics generated. The &lt;a href="http://metric-fu.rubyforge.org/"&gt;metric_fu&lt;/a&gt; project does a great job of this: with just one rake task, you can summon stats from &lt;a href="http://ruby.sadi.st/Flay.html"&gt;Flay&lt;/a&gt;, &lt;a href="http://ruby.sadi.st/Flog.html"&gt;Flog&lt;/a&gt;, &lt;a href="http://github.com/relevance/rcov/tree/master"&gt;RCov&lt;/a&gt;, &lt;a href="http://github.com/martinjandrews/roodi/tree/master"&gt;Roodi&lt;/a&gt;, &lt;a href="http://wiki.github.com/kevinrutherford/reek"&gt;Reek&lt;/a&gt;, and more. That’s decent for one project, but for nearly 20 it doesn’t work so well. I ended up hacking a script together that does the following for each project that lives in the Integrity database:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Runs metric_fu to generate stats&lt;/li&gt;
		&lt;li&gt;Compares the last run to the current one to see if there’s any difference&lt;/li&gt;
		&lt;li&gt;Alerts Campfire using &lt;a href="http://tinder.rubyforge.org/"&gt;Tinder&lt;/a&gt; if there’s changes&lt;/li&gt;
		&lt;li&gt;Logs the run in a Google Spreadsheet using &lt;a href="http://github.com/gimite/google-spreadsheet-ruby/"&gt;google-spreadsheet-ruby&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;So around 4 times daily we get updates as to how &amp;lt;s&gt;bad&amp;lt;/s&gt; good our code is, and eventually we’ll start seeing some trends in the spreadsheets. I also hacked a custom template based on Integrity’s layout so it’s easier to browse the metrics, which is available in &lt;a href="http://github.com/qrush/metric_fu/tree/master"&gt;my fork&lt;/a&gt;. The next step is to integrate the tools into the Integrity build script, which we’re still in the process of deciding &lt;a href="http://giantrobots.thoughtbot.com/2008/10/22/test-metrics-in-your-rails-app-and-what-they-mean"&gt;what factors&lt;/a&gt; will determine a failure.&lt;/p&gt;


	&lt;p&gt;The metrics are up and available at &lt;a href="http://metrics.thoughtbot.com"&gt;http://metrics.thoughtbot.com&lt;/a&gt; if you’d like to browse around.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://metrics.thoughtbot.com/hoptoad_notifier/output/reek.html"&gt;&lt;img src="http://farm4.static.flickr.com/3414/3576376858_bed5e73382.jpg" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Both of these projects have been a lot of fun to work on. So far there’s no penalties for breaking the build, but there are plenty of &lt;a href="http://lh4.ggpht.com/AGWSpilot16/R-vWmqnaDMI/AAAAAAAAArs/k4OxhzrZFQ4/s400/Nerf+N-Strike+Vulcan.jpg"&gt;&lt;span class="caps"&gt;NERF&lt;/span&gt; guns&lt;/a&gt; around the office if we feel the need for retaliation. The Reek and Roodi metrics results have been quite enlightening and they seem to give great suggestions for refactoring. As for the trends, perhaps I’ll report back in a future edition of the Chronicles on the progress!&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/5/29/internbot-chronicles-4</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Matt Jankowski</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-05-26:8430</id>
    <published>2009-05-26T21:49:00Z</published>
    <updated>2009-05-27T12:10:59Z</updated>
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/2S99g7-b7po/ten-days-of-thunder-thimble" rel="alternate" type="text/html" />
    <title>Ten days of Thunder Thimble</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/26/tt_logo_gr.jpg" alt="logo" /&gt;&lt;/p&gt;


	&lt;p&gt;Since &lt;a href="http://giantrobots.thoughtbot.com/2009/5/15/product-launch-thunder-thimble"&gt;last weeks launch&lt;/a&gt; of &lt;a href="http://www.thunderthimble.com/"&gt;Thunder Thimble&lt;/a&gt; we’ve received some great feedback from early users.  Thanks to everyone who checked this out.  We’ve deployed a few interesting changes since then, as well.&lt;/p&gt;


	&lt;h2&gt;Bug fixes&lt;/h2&gt;


	&lt;p&gt;There were times during a search update where one brand’s search having any issues (ie, it was an invalid search, or twitter was down, or twitter responded with an unexpected response, or there was a network timeout, etc) could have lead to subsequent searches not being updated.  If you created an account in the first ~24 hours or so after launch and then didn’t see any results for a while, this is probably what was happening.  We’ve added every error that’s occurred so far to the updating task, and we continue to add the new ones as they happen (thanks to &lt;a href="http://www.hoptoadapp.com"&gt;Hoptoad&lt;/a&gt; for some nice logging).  So, if this is you and you gave up right away, you might want to check back for new results today.&lt;/p&gt;


	&lt;p&gt;If you &lt;span class="caps"&gt;STILL&lt;/span&gt; aren’t seeing any results but think you should be, contact us via twitter @thunderthimble, or via the getsatisfaction help site.&lt;/p&gt;


	&lt;h2&gt;UI changes
&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/26/ratings-buttons2.jpg" alt="ratings" /&gt;&lt;/h2&gt;


	&lt;p&gt;Early last week we deployed a UI change to the “global dashboard” and “brand dashboard” views within the application.  This change brought the “positive”, “negative” and “ignore” UI elements closer to the user, and now requires less back and forth between a “deep” page and the dashboard to do these common actions.  It’s also easier to see recent trends and latest activity at a quick glance with this change.&lt;/p&gt;


	&lt;h2&gt;New feature – tweet from the application&lt;/h2&gt;


	&lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/26/magick2.jpg" alt="the magic key" /&gt;&lt;/p&gt;


	&lt;p&gt;When we launched, you could send a twitter &lt;span class="caps"&gt;REPLY&lt;/span&gt; to a message we found for you with the monitoring service, but you could not initiate a tweet directly from Thunder Thimble itself.  From our own internal use of the product, this was the one thing that we kept expecting to be able to do and finding we couldn’t (yes, we are surprised by the lack of features even in things we built!).&lt;/p&gt;


	&lt;p&gt;As of today, you can use the “Post a new Twitter update” link from the brand dashboard page to initiate a tweet as any account you have hooked up to TT (at the account, brand and user levels, that is).  We default to the brand you’re on, but allow you to change that prior to sending.  You can also use the backtick key &amp;mdash; &lt;code&gt;`&lt;/code&gt; &amp;mdash; as a keyboard shortcut to access this feature from anywhere in the application.&lt;/p&gt;


	&lt;p&gt;&lt;br /&gt;&lt;/p&gt;


&amp;lt;object height="370" width="550"&gt;&amp;lt;param&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;

	&lt;h2&gt;Fluid.app icon&lt;/h2&gt;


	&lt;p&gt;For users of &lt;a href="http://fluidapp.com/"&gt;Fluid&lt;/a&gt; we have a 512×512 &lt;span class="caps"&gt;PNG&lt;/span&gt; file for you &lt;a href="http://app.thunderthimble.com/images/fluid-icon.png"&gt;here&lt;/a&gt; which is guaranteed to look awesome in your &lt;span class="caps"&gt;OS X&lt;/span&gt; dock.  This icon should be picked up automatically when you setup your fluid application for Thunder Thimble.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/26/BYyWCJRDnno8gnauBc5BBRjYo1_500.jpg" alt="fluid icon" /&gt;&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/5/26/ten-days-of-thunder-thimble</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Dan Croak</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-05-18:8343</id>
    <published>2009-05-18T19:36:00Z</published>
    <updated>2009-05-18T19:39:05Z</updated>
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/XDhAi1PWhOM/10-reasons-you-should-be-listening-to-the-rails-envy-podcast" rel="alternate" type="text/html" />
    <title>10 reasons you should be listening to the Rails Envy Podcast</title>
<content type="html">
            &lt;p&gt;As sports fans go, we’ve been very lucky over the past few years in Boston. The Red Sox, Patriots, &amp; Celtics have all won championships.&lt;/p&gt;


	&lt;p&gt;To me, the best part about having competitive teams from your city is the extra entertainment it gives you for weeks or even months. Each round your team advances is exciting and it gives you something to talk about with your friends. The city takes on a certain buzz on game days, and you see lots of people wearing the team’s colors.&lt;/p&gt;


	&lt;p&gt;Another thing I enjoy about the playoffs is “mayoral bets”. For example, during the Super Bowl two years ago, New York and Boston were competing. The mayors from each city made a gentleman’s bet:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;If the Patriots win, that means Bloomberg will send a delivery to Boston that includes Manhattan clam chowder, pastrami sandwiches, New York pizzas, black and white cookies, New York steaks and a few gallons of lemon ice. And if the Giants claim victory, Menino will send a package with New England Clam Chowder, Dunkin’ Donuts coffee, Boston cream pies, chicken sausages and Brigham’s ice cream.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;I don’t know who gets to feast on the spoils, but in the same spirit, &lt;a href="http://thoughtbot.com"&gt;thoughtbot&lt;/a&gt; and &lt;a href="http://railsenvy.com"&gt;Rails Envy&lt;/a&gt; made a bet while at &lt;a href="http://giantrobots.thoughtbot.com/2009/5/12/railsconf-2009-wrapup"&gt;Railsconf in Vegas&lt;/a&gt; for the Boston Celtics-Orlando Magic series.&lt;/p&gt;


	&lt;p&gt;The terms were simple: if the team from your city wins, highlight the other company’s work in your favorite medium. For us, that’s the &lt;a href="http://giantrobots.thoughtbot.com"&gt;Giant Robots blog&lt;/a&gt;, and for Rails Envy, it’s the &lt;a href="http://railsenvy.com/podcast"&gt;Rails Envy podcast&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;Unfortunately, Boston’s title defense ended last night as Orlando won the series, taking our dream of having an entire rails envy podcast dedicated solely to thoughtbot down with it. So, without further ado, I present to you the &lt;strong&gt;Top 10 reasons you should be listening to the Rails Envy podcast&lt;/strong&gt;.&lt;/p&gt;


&lt;div&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/18/waynes-top-ten_tiny.jpg?1242674718" alt="Wayne &amp;amp;#38; Garth share their Top 10" /&gt;&lt;/div&gt;

	&lt;h2&gt;10&lt;/h2&gt;


	&lt;p&gt;The production value is far above the usual internet fare, and even some &lt;a href="http://www.youtube.com/watch?v=Fa7ck5mcd1o"&gt;Hollywood fare&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;9&lt;/h2&gt;


	&lt;p&gt;Their ability to mangle the names of Rails developers fills a gaping void left by former President Bush. Laughing at people mis-speak is as natural as laughing at a &lt;a href="http://www.snpp.com/episodes/2F31.html"&gt;football to the groin&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;8&lt;/h2&gt;


	&lt;p&gt;They’re like the &lt;a href="http://www.msnbc.msn.com/id/3403008/"&gt;Meet the Press&lt;/a&gt; of the Rails world: once a week, they hit you in the face with the best Rails knowledge you can find anywhere.&lt;/p&gt;


	&lt;h2&gt;7&lt;/h2&gt;


	&lt;p&gt;They put their money where their mouth is and have the guts to bet on sporting events with other members of the community.&lt;/p&gt;


	&lt;h2&gt;6&lt;/h2&gt;


	&lt;p&gt;They always include a few things on bleeding edge, such as &lt;a href="http://tokyocabinet.sourceforge.net/index.html"&gt;Tokyo Cabinet&lt;/a&gt; in their &lt;a href="http://railsenvy.com/2009/5/14/rails-envy-podcast-episode-078-05-14-2009"&gt;latest podcast&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;5&lt;/h2&gt;


	&lt;p&gt;They read &lt;span class="caps"&gt;RSS&lt;/span&gt; and Twitter so you don’t have to, leaving you plenty of time &lt;a href="http://blip.tv/file/2086222"&gt;to do neck exercises&lt;/a&gt;, increasing the blood to your brain.&lt;/p&gt;


	&lt;h2&gt;4&lt;/h2&gt;


	&lt;p&gt;No fluff, just stuff. They don’t “report” on the drama in the Rails community. Look through their show notes. It’s all practical information that you can use as a Rails developer. If there’s a technical reason to care, they deliver a level-headed analysis (example: Ruby v. Scala in &lt;a href="http://railsenvy.com/2009/4/15/rails-envy-podcast-episode-075-04-15-2009"&gt;Episode #75&lt;/a&gt;).&lt;/p&gt;


	&lt;h2&gt;3&lt;/h2&gt;


	&lt;p&gt;Much like their city’s basketball players, they are both a frightening seven feet tall. Thank god they mostly work in audio.&lt;/p&gt;


	&lt;h2&gt;2&lt;/h2&gt;


	&lt;p&gt;They frequently highlight &lt;strong&gt;thoughtbot’s&lt;/strong&gt; stuff and came up with an amazing “Giant Robots Smashing into Other Giant Robots” (&lt;strong&gt;&lt;span class="caps"&gt;CRASH&lt;/span&gt;!&lt;/strong&gt;) sound.&lt;/p&gt;


	&lt;h2&gt;1&lt;/h2&gt;


	&lt;p&gt;Gregg and Jason are both guys that seem to really enjoy what they’re doing.  They clearly care about the community in both professional and social aspects, and are consistently giving talks, presenting at conferences, etc.&lt;/p&gt;


&lt;div&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/18/greggjason.jpg.jpeg" alt="Let them eat cake" /&gt;&lt;/div&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/5/18/10-reasons-you-should-be-listening-to-the-rails-envy-podcast</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Matt Jankowski</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-05-15:8309</id>
    <published>2009-05-15T20:16:00Z</published>
    <updated>2009-05-15T20:25:46Z</updated>
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/lZXBcj3go78/product-launch-thunder-thimble" rel="alternate" type="text/html" />
    <title>Product Launch: Thunder Thimble</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/15/thunderthimble-apple-touch-icon.png" alt="" /&gt;&lt;/p&gt;


	&lt;p&gt;We’re pleased to announce the launch of our next product &amp;mdash; which is a web based product called &lt;a href="http://thunderthimble.com/"&gt;Thunder Thimble&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;For regular readers, yes – this is the same application whose initial prototype was mentioned here in &lt;a href="http://giantrobots.thoughtbot.com/2009/3/5/how-we-accidentally-redesign-a-product-in-a-week"&gt;how we accidentally redesigned a product in a week&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Overview&lt;/h2&gt;


	&lt;p&gt;Thunder Thimble is a web based application meant for monitoring and managing mentions of your products, services, brands in “social media”.  For now, this means twitter support only.  In the future, we may add blogs, news, videos, facebook, etc – or even more “mainstream” web content, but the intention is really to monitor “current” topics and trends as opposed to all time mentions, and twitter makes the most sense for this right now.&lt;/p&gt;


	&lt;h2&gt;Use case&lt;/h2&gt;


	&lt;p&gt;At thoughtbot, we have four areas of operation.  First, our consulting service, which is the core of our business and for which “thoughtbot” is really the only brand name involved.  Second, our products like &lt;a href="http://widgetfinger.com"&gt;WidgetFinger&lt;/a&gt; and &lt;a href="http://www.hoptoadapp.com"&gt;Hoptoad&lt;/a&gt; and &lt;a href="http://teebot.thoughtbot.com"&gt;TeeBot&lt;/a&gt;.  Third, our “fun” projects like &lt;a href="http://umbrellatoday.com"&gt;Umbrella Today&lt;/a&gt; and &lt;a href="http://www.stocknames.info/"&gt;Stock Names&lt;/a&gt;.  Finally, our open source projects like Shoulda, Paperclip, Factory Girl, Squirrel, etc.&lt;/p&gt;


	&lt;p&gt;Whether it’s to send us praise or complaints, comments or questions – we really love hearing from people about our work.  The common problem we faced monitoring and responding to all of this feedback was that we had a plethora of twitter accounts, support address, contact forms, and so on – and we had different people (with no real official responsibility to do so) attempting to manage all of that.&lt;/p&gt;


	&lt;p&gt;We would also have a “feeling” that – for example – Hoptoad was getting mostly positive feedback on twitter, but we had never really had any hard metrics to back that up.  We’ve been using the Thunder Thimble application ourselves for two months now, and it solves basically all of those problems.&lt;/p&gt;


	&lt;h2&gt;Features&lt;/h2&gt;


	&lt;p&gt;Now we have a scenario where…&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Multiple people from thoughtbot constantly monitor each of our brands (we have rss support for mentions within a brand and across the entire account – this replaces google alerts and twitter search for many of us)&lt;/li&gt;
		&lt;li&gt;We can flag tweets as positive or negative, and see trends over time in a handsome line graph&lt;/li&gt;
		&lt;li&gt;We can embed a javascript widget in a website, which shows recent positively rated tweets&lt;/li&gt;
		&lt;li&gt;We can reply to messages directly from the tool itself&lt;/li&gt;
		&lt;li&gt;We can reply from the relevant account (business, product, personal) depending on the message we’re replying to&lt;/li&gt;
		&lt;li&gt;We can even enter competitor or complimentor brands, and respond to mentions of those if needed&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Recent brand activity&lt;/h2&gt;


	&lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/14/Picture_3.png" alt="" /&gt;&lt;/p&gt;


	&lt;h2&gt;Free plans&lt;/h2&gt;


	&lt;p&gt;You can &lt;a href="http://app.thunderthimble.com/users/new"&gt;sign up today&lt;/a&gt; and check out the product – there’s a even a &lt;span class="caps"&gt;FREE&lt;/span&gt; plan so that you can take it on a trial run for 30 days before you commit to a paid account.&lt;/p&gt;


	&lt;h2&gt;Feedback&lt;/h2&gt;


	&lt;p&gt;Thanks to our beta testers for feedback during the last month or so – we think have a tool that’s at least more valuable than not using it, and we’ve got big plans for the coming months as well!&lt;/p&gt;


	&lt;p&gt;We’ve got a &lt;a href="http://getsatisfaction.com/thoughtbot/products/thoughtbot_thunder_thimble"&gt;getsatisfaction&lt;/a&gt; account set up to handle feedback and feature requests, so let us know what you think.  We look forward to continue expanding the product in the future.&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/5/15/product-launch-thunder-thimble</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Nick Quaranto</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-05-12:8271</id>
    <published>2009-05-12T20:39:00Z</published>
    <updated>2009-05-12T20:42:37Z</updated>
    <category term="Development" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/p4d2zCJ5vpM/railsconf-2009-wrapup" rel="alternate" type="text/html" />
    <title>RailsConf 2009 Wrapup</title>
<content type="html">
            &lt;div&gt;&lt;a href="http://www.flickr.com/photos/konklone/3520474245/"&gt;&lt;img src="http://farm4.static.flickr.com/3398/3520474245_933cf3c3e2_m.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;p&gt;Now that the fun and games are over and the Rails world is returning to work, this is a great time to appreciate some of the wisdom that was imparted to us last week during RailsConf. We’d also like to thank those who showed up for the &lt;a href="http://giantrobots.thoughtbot.com/2009/5/6/vanquish-thoughtbot-at-the-poker-table"&gt;Poker Tournament&lt;/a&gt; and made it a great time for all.&lt;/p&gt;


	&lt;p&gt;If you missed the conference, be sure to check out the &lt;a href="http://railsconf.blip.tv/"&gt;keynotes at blip.tv&lt;/a&gt; and also &lt;a href="http://litanyagainstfear.com/blog/2009/05/05/railsconf-2009-notes/"&gt;my expansive set of notes&lt;/a&gt; on the talks I attended.&lt;/p&gt;


	&lt;p&gt;Now, the tiny robots have some reflections on what they’ve learned and would like to share:&lt;/p&gt;


	&lt;h2&gt;Nick&lt;/h2&gt;


	&lt;p&gt;One of my favorite talks was Scott Chacon’s &lt;a href="http://litanyagainstfear.com/blog/2009/05/05/railsconf-2009-smacking-git-around/"&gt;Smacking Git Around&lt;/a&gt;. It was a great source of information for those new to Git and those who have been using it for a while. Also, &lt;a href="http://rack.rubyforge.org/"&gt;Rack has seriously arrived&lt;/a&gt; in the Ruby world and is pretty much essential to learn.&lt;/p&gt;


	&lt;h2&gt;Matt&lt;/h2&gt;


	&lt;p&gt;You’ll think I’m kidding, because of &lt;a href="http://search.twitter.com/search?q=+ferriss+%23railsconf"&gt;this&lt;/a&gt;, but the Tim Ferriss keynote (fireside chat?) was probably the best part of RailsConf.  Please understand that I do 600 pushups on the roof top of my apartment building every morning at 3:30AM though, so your mileage may vary.  I also change my own oil in my car—which has a quarter million miles on it and still runs like a champ.&lt;/p&gt;


	&lt;h2&gt;Jon&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://blog.objectmentor.com/"&gt;Uncle Bob’s&lt;/a&gt; keynote was one of the best keynotes I’ve heard at a RailsConf. While he was preaching to the choir a bit about &lt;span class="caps"&gt;TDD&lt;/span&gt;, it needed to be said. Plus the idea that not only is professionalism important, but it’s not the stodgy three-piece-suit some people seem to think it is, is a meme that needs circulating.&lt;/p&gt;


	&lt;p&gt;In that light, &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/7897"&gt;Ezra’s talk (partially) about automated and verifiable server deployments&lt;/a&gt; as well as Marty Andrew’s talk about &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/6752"&gt;automated code quality metrics&lt;/a&gt; spoke a bit more to me than they probably would have (although they would have been interesting on their own, regardless!)&lt;/p&gt;


	&lt;p&gt;Of course, nothing will top Eric Torrey’s explanation of why fixing the problem at its root is better than temporary fixes:&lt;/p&gt;


	&lt;p&gt;&amp;lt;object height="344" width="425"&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;embed src="http://www.youtube.com/v/AXHTDIqE8YI&amp;amp;#38;hl=en&amp;amp;#38;fs=1" height="344" width="425"&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;/p&gt;


	&lt;h2&gt;Jason&lt;/h2&gt;


&lt;div&gt;&lt;a href="http://www.flickr.com/photos/ig/3505365262/"&gt;&lt;img src="http://farm4.static.flickr.com/3644/3505365262_ef36b18ccf_m.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;p&gt;My favorite three things that I learned about at RailsConf were learning how to monitor and manage distributed computational tasks using Amazon Web Services with Matt Wood’s &lt;a href="http://github.com/mza/mission-control/tree/master"&gt;Mission Control&lt;/a&gt;, using FunFX to &lt;a href="http://wiki.github.com/aslakhellesoy/cucumber/funfx-and-flex"&gt;test your Flash (and Flex) applications with Cucumber&lt;/a&gt;, and &lt;a href="http://code.google.com/p/appengine-jruby/wiki/GettingStarted"&gt;running Rack apps on Google AppEngine&lt;/a&gt; with some helpful &lt;a href="http://www.infoq.com/news/2009/04/datamapper-datastore-reggae"&gt;related tools&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Mike&lt;/h2&gt;


	&lt;p&gt;The most interesting talk for me was the &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/8680"&gt;What Makes Ruby Go: An Implementation Primer&lt;/a&gt; talk, where we learned how Object#extend can kill your method cache and just how slow global constants really are. Other highlights include seeing the toad from Hoptoad on the big screen while I learned about the ins-and-outs of using Rack in Rails, and seeing all the people I only get to see at Rails conferences.&lt;/p&gt;


	&lt;h2&gt;Chad&lt;/h2&gt;


	&lt;p&gt;As mentioned above, Rack is where its at, and it will continue to enable a lot of coolness in Rails.  One of the best talks I’ve seen on Rack, at any conference, was &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/7717"&gt;And the Greatest of These Is … Rack Support&lt;/a&gt;, by Ben Scofield.  A lot of the Rack talks I’ve seen have been rather abstract to date.  Things have started to clearly started to gel with Rack, and Ben was able to give an excellent, concise overview of the current capabilities of Rack support in Rails, and some ways in which it can be used.&lt;/p&gt;


	&lt;h2&gt;Joe&lt;/h2&gt;


&lt;div&gt;&lt;a href="http://www.flickr.com/photos/ig/3504541863/"&gt;&lt;img src="http://farm4.static.flickr.com/3401/3504541863_12cae3b4ab_m.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;p&gt;I enjoyed &lt;a href="http://en.oreilly.com/rails2009/public/schedule/detail/6752"&gt;Automated Code Quality Checking In Ruby And Rails&lt;/a&gt; – it gave us the kick we needed to add code quality tools to our CI process. I also found out about some tools (like “Roodi”) that I had never heard of before. As usual, though, my favorite part was being able to discuss code with the author in person, as well as getting to see some of the people in our community that I only see at conferences.&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/5/12/railsconf-2009-wrapup</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Dan Croak</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-05-06:8250</id>
    <published>2009-05-06T22:30:00Z</published>
    <updated>2009-05-06T22:30:57Z</updated>
    <category term="poker" />
    <category term="railsconf" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/oBdyEUNLMhg/vanquish-thoughtbot-at-the-poker-table" rel="alternate" type="text/html" />
    <title>Vanquish thoughtbot at the poker table</title>
<content type="html">
            &lt;blockquote&gt;
		&lt;p&gt;“If you even dream of beating me you’d better wake up and apologize.” – Muhammed Ali&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Not since the &lt;a href="http://en.wikipedia.org/wiki/Thrilla_in_Manila"&gt;Thrilla in Manila&lt;/a&gt; has there been a contest so hyped, with so much on the line. This is bound to be the most remarkable, exceptional event in Vegas all year.&lt;/p&gt;


	&lt;p&gt;Of course I refer to…&lt;/p&gt;


	&lt;h2&gt;The 2009 Railsconf Poker Tournament&lt;/h2&gt;


	&lt;p&gt;We’re pleased to announce a no-limit Texas Hold ‘Em poker tournament tomorrow night (Thursday) at 9pm at &lt;a href="http://is.gd/xjNn"&gt;The Poker Room at Caesar’s Palace&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;The buy-in is $65. Caesar’s takes $15 from each person to set everything up for us. We’ll have our own dealers, and the casino handles everything.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Winner takes the rest.&lt;/strong&gt;&lt;/p&gt;


&lt;div&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/5/6/caesars-las-vegas_tiny.jpg?1241648745"&gt;&lt;/div&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/5/6/vanquish-thoughtbot-at-the-poker-table</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Nick Quaranto</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-04-24:8182</id>
    <published>2009-04-24T16:04:00Z</published>
    <updated>2009-04-24T16:05:07Z</updated>
    <category term="Development" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/fUgp_S7oBpQ/internbot-chronicles-3-2" rel="alternate" type="text/html" />
    <title>Internbot Chronicles #3</title>
<content type="html">
            &lt;p&gt;Now that testing is a normal part of my daily workflow, I think it’s a great time to go over some of the testing tools that I use here at thoughtbot.&lt;/p&gt;


	&lt;h2&gt;Shoulda&lt;/h2&gt;


	&lt;p&gt;Typing too much makes testing no fun at all. I’m actually coming from the RSpec world, and thankfully it was pretty easy to switch over to &lt;a href="http://github.com/thoughtbot/shoulda/tree/master"&gt;Shoulda&lt;/a&gt; from it. Here’s what I like best about it:&lt;/p&gt;


&lt;div&gt;&lt;a href="http://www.flickr.com/photos/mundane_joy/2232153944/"&gt;&lt;img src="http://farm3.static.flickr.com/2159/2232153944_d376d5a2f2_m.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;context&lt;/code&gt; and &lt;code&gt;setup&lt;/code&gt; blocks makes testing ridiculously simple and &lt;span class="caps"&gt;DRY&lt;/span&gt;.&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;before_should&lt;/code&gt;: Basically, you can set up expectations with your favorite mocking framework in these blocks, which run before the &lt;code&gt;setup&lt;/code&gt; block in the given &lt;code&gt;context&lt;/code&gt;.&lt;/li&gt;
		&lt;li&gt;Macros that just save tons of time. Simple ones like &lt;code&gt;should_redirect_to&lt;/code&gt; are actions that need to be tested all the time, and luckily there’s a whole suite of them for both &lt;a href="http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActiveRecord/Macros.html"&gt;ActiveRecord&lt;/a&gt; and &lt;a href="http://dev.thoughtbot.com/shoulda/classes/Shoulda/ActionController/Macros.html"&gt;ActionController&lt;/a&gt;. &lt;/li&gt;
		&lt;li&gt;Custom macros that can be easily dropped in to test the same actions in multiple places. I do miss RSpec’s &lt;code&gt;it_should_behave_like&lt;/code&gt; though, but this works decently.&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h2&gt;Mocha&lt;/h2&gt;


	&lt;p&gt;The concept of mocking and stubbing in general is somewhat new to me, and it’s definitely been difficult to learn how to use effectively. It’s starting to become natural though, and I don’t mind the speedup that testing in isolation gives. The majority of our projects use &lt;a href="http://mocha.rubyforge.org"&gt;Mocha&lt;/a&gt;, which does the job just fine. I’ve also been looking into &lt;a href="http://github.com/btakita/rr/tree/master"&gt;RR&lt;/a&gt;, which has a &lt;a href="http://technicalpickles.com/posts/ruby-stubbing-and-mocking-with-rr/"&gt;much cleaner syntax and some additional features&lt;/a&gt;, but usually my daily mocking is done with Mocha. The most important thing for me to remember is to avoid situations where test pass but the code is broken due to excessive stubbing of behavior. The sweet spot with this is to use integration testing to cover all the bases.&lt;/p&gt;


	&lt;h2&gt;factory_girl&lt;/h2&gt;


&lt;div&gt;&lt;a href="http://www.flickr.com/photos/marxalot/3319031986"&gt;&lt;img src="http://farm4.static.flickr.com/3345/3319031986_6eaa4c50b1_m.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;p&gt;If you’ve ever dealt with the frustration that is Rails fixtures, then you know the &lt;a href="http://github.com/thoughtbot/factory_girl/tree/master"&gt;breath of relief that factories&lt;/a&gt; can give your tests. Being able to generate new models with a simple &lt;code&gt;Factory(:post)&lt;/code&gt; call makes testing ridiculously easy. Some of the latest features I’ve been using is the &lt;code&gt;:parent&lt;/code&gt; option on &lt;code&gt;Factory.define&lt;/code&gt;, which allows you inherit attributes from another factory. &lt;a href="http://github.com/thoughtbot/clearance/blob/master/generators/clearance/templates/factories.rb"&gt;Clearance has a great example of this&lt;/a&gt; in how it creates a &lt;code&gt;Factory(:email_confirmed_user)&lt;/code&gt; that descends from &lt;code&gt;Factory(:user)&lt;/code&gt;.&lt;/p&gt;


	&lt;h2&gt;Cucumber&lt;/h2&gt;


	&lt;p&gt;I’ve learned about user stories in classes, but being able to write them in plain English and run them with Ruby has totally blown me away. Outside-in development is a great way to approach features that need to be built and tested from the ground up. &lt;a href="http://mwrc2009.confreaks.com/14-mar-2009-15-00-bdd-with-cucumber-ben-mabey.html"&gt;Ben Mabey’s presentation at MountainWest RubyConf&lt;/a&gt; has a great example of how this development method works if you haven’t tried it out yet. The best part I find is that it can be read by clients or developers coming into the project, and it can be used outside of the Rails environment as well. Take some time and look into Cucumber if you haven’t already, and &lt;a href="http://cukes.info"&gt;start at their fantastic site&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;FakeWeb&lt;/h2&gt;


	&lt;p&gt;Mocking out external &lt;span class="caps"&gt;HTTP&lt;/span&gt; calls is difficult. If you’re working with any sort of &lt;span class="caps"&gt;API&lt;/span&gt; from another site and you want to ensure that your code is actually submitting to it, relying on &lt;a href="http://fakeweb.rubyforge.org"&gt;FakeWeb&lt;/a&gt; is a good choice. The syntax and setup is really simple, and it will usually look something like this:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;fake_web&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;FakeWeb&lt;/span&gt;.allow_net_connect = &lt;span class="pc"&gt;false&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;FakeWeb&lt;/span&gt;.register_uri(&lt;span class="sy"&gt;:post&lt;/span&gt;, &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;http://somesite.com&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;, &lt;tt&gt;
&lt;/tt&gt;  &lt;span class="sy"&gt;:string&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;response body&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;)&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;This little snippet will cause FakeWeb to throw errors if any other &lt;span class="caps"&gt;HTTP&lt;/span&gt; calls are made outside of the ones registered. The final line will tell the library to return the given string when that &lt;span class="caps"&gt;URL&lt;/span&gt; is hit from the application with a &lt;span class="caps"&gt;POST&lt;/span&gt; request. Like most projects in the Ruby world, it “just works”.&lt;/p&gt;


	&lt;h2&gt;Testing in your shell&lt;/h2&gt;


&lt;div&gt;&lt;a href="http://www.flickr.com/photos/sha_junglii/2553559302"&gt;&lt;img src="http://farm3.static.flickr.com/2054/2553559302_10afed54bf_m.jpg" /&gt;&lt;/a&gt;&lt;/div&gt;

	&lt;p&gt;Being a &lt;a href="http://giantrobots.thoughtbot.com/2009/4/8/integrating-vim-into-your-life"&gt;convert to vim from TextMate&lt;/a&gt;, running tests usually isn’t as simple as doing Cmd+R. Luckily there’s two tools that help out with this. One is &lt;a href="http://zentest.rubyforge.org/ZenTest/"&gt;autotest&lt;/a&gt;, which I’ll run if the test suite for the app I’m working with doesn’t take too long. What I love best is that it fires off the test immediately after a &lt;code&gt;:w&lt;/code&gt; in vim, so I don’t have to do any sort of context switching to run the test. It can get annoying though, and modifying your &lt;code&gt;~/.autotest&lt;/code&gt; to &lt;a href="http://gist.github.com/98663"&gt;not run the entire suite after fixing a failed test&lt;/a&gt; helps cut that down. Another helpful thing that some of the thoughtbotters use is a &lt;a href="http://gist.github.com/101130"&gt;zsh script that adds autocompletion&lt;/a&gt; for running unit and functional tests. Basically just type &lt;code&gt;tu&lt;/code&gt; or &lt;code&gt;tf&lt;/code&gt;, and tab away.&lt;/p&gt;


	&lt;p&gt;If you know of other testing tools that we should be looking into, speak up in the comments!&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/4/24/internbot-chronicles-3-2</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Dan Croak</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-04-23:8155</id>
    <published>2009-04-23T17:23:00Z</published>
    <updated>2009-04-23T17:36:03Z</updated>
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/GTUg7hg9gUo/tips-for-writing-your-own-rails-engine" rel="alternate" type="text/html" />
    <title>Tips for writing your own Rails engine</title>
<content type="html">
            &lt;p&gt;While converting &lt;a href="http://giantrobots.thoughtbot.com/2009/4/22/clearance-is-a-rails-engine"&gt;Clearance to a Rails engine&lt;/a&gt; was easy, once we were there, we found it wasn’t Valhalla.&lt;/p&gt;


&lt;div&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/4/22/viking_funeral.jpg" alt="Viking Funeral" width="450" /&gt;&lt;/div&gt;

	&lt;p&gt;We fixed the bugs while using the engine internally on a few apps. Here are the lessons we learned. Keep them in mind if you’re thinking of writing your own engine.&lt;/p&gt;


&lt;div&gt;&amp;lt;object height="344" width="425"&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;embed src="http://www.youtube.com/v/tSHM5FiOChY&amp;amp;#38;hl=en&amp;amp;#38;fs=1" height="344" width="425"&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;/div&gt;

	&lt;h2&gt;Routes precedence&lt;/h2&gt;


	&lt;p&gt;As developers, we want &lt;strong&gt;routes in our app to take precedence over routes in the engine&lt;/strong&gt;. That is not the default behavior.&lt;/p&gt;


	&lt;p&gt;To get around that, we came up with this hack. (credit to Nick Quaranto, a.k.a. qrush a.k.a. Internbot)&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;ActionController::Routing::RouteSet&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;load_routes_with_clearance!&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    clearance_routes = &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;File&lt;/span&gt;.dirname(&lt;span class="pc"&gt;__FILE__&lt;/span&gt;), &lt;tt&gt;
&lt;/tt&gt;                       *&lt;span class="s"&gt;&lt;span class="dl"&gt;%w[&lt;/span&gt;&lt;span class="k"&gt;.. config clearance_routes.rb&lt;/span&gt;&lt;span class="dl"&gt;]&lt;/span&gt;&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;unless&lt;/span&gt; configuration_files.include? clearance_routes&lt;tt&gt;
&lt;/tt&gt;      add_configuration_file(clearance_routes)&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    load_routes_without_clearance!&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;  alias_method_chain &lt;span class="sy"&gt;:load_routes!&lt;/span&gt;, &lt;span class="sy"&gt;:clearance&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Rather than using the Rails engine convention of naming the routes file &lt;code&gt;vendor/gems/clearance/config/routes.rb&lt;/code&gt;, we named it &lt;code&gt;vendor/gems/clearance/config/clearance_routes.rb&lt;/code&gt; so it won’t be automatically loaded. Then we &lt;code&gt;alias_method_chain&lt;/code&gt; around some &lt;code&gt;ActionController&lt;/code&gt; internals.&lt;/p&gt;


	&lt;p&gt;Ugly stuff, but effective and solved a blocker for releasing as an engine.&lt;/p&gt;


	&lt;h2&gt;Cached classes in development&lt;/h2&gt;


	&lt;p&gt;In development, all your classes are constantly reloaded. This makes sense for your app, but not for your engine classes or modules.&lt;/p&gt;


	&lt;p&gt;We added &lt;a href="http://apidock.com/rails/ActiveSupport/Dependencies/Loadable/unloadable"&gt;unloadable&lt;/a&gt; to our &lt;code&gt;Clearance&lt;/code&gt; module to fix this. Again, credit goes to Nick.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;Clearance::SessionsController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ApplicationController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  unloadable&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;If you see errors like the following, you might consider a similar approach.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;has been removed from the module tree but is still active&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h2&gt;Namespacing controllers&lt;/h2&gt;


	&lt;p&gt;We decided namespacing controllers was a good convention for our engine.&lt;/p&gt;


	&lt;p&gt;When we need to override something in the engine, this gives us clear routes separation…&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;10&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;11&lt;tt&gt;
&lt;/tt&gt;12&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="c"&gt;# in the engine&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;Routing&lt;/span&gt;::&lt;span class="co"&gt;Routes&lt;/span&gt;.draw &lt;span class="r"&gt;do&lt;/span&gt; |map|&lt;tt&gt;
&lt;/tt&gt;  map.resources &lt;span class="sy"&gt;:users&lt;/span&gt;, &lt;span class="sy"&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;clearance/users&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt; |users|&lt;tt&gt;
&lt;/tt&gt;    users.resource &lt;span class="sy"&gt;:password&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="sy"&gt;:controller&lt;/span&gt; =&amp;gt; &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;clearance/passwords&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;      &lt;span class="sy"&gt;:only&lt;/span&gt; =&amp;gt; [&lt;span class="sy"&gt;:create&lt;/span&gt;, &lt;span class="sy"&gt;:edit&lt;/span&gt;, &lt;span class="sy"&gt;:update&lt;/span&gt;]&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="c"&gt;# in the app&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;Routing&lt;/span&gt;::&lt;span class="co"&gt;Routes&lt;/span&gt;.draw &lt;span class="r"&gt;do&lt;/span&gt; |map|&lt;tt&gt;
&lt;/tt&gt;  map.resources &lt;span class="sy"&gt;:users&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;... and clean subclassing:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;UsersController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Clearance&lt;/span&gt;::&lt;span class="co"&gt;UsersController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;edit&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    ...&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;h2&gt;Helper inclusion&lt;/h2&gt;


	&lt;p&gt;Tammer has also recently been extracting the announcement code from &lt;a href="http://hoptoadapp.com"&gt;Hoptoad&lt;/a&gt; into an engine. He found that &lt;code&gt;helper :all&lt;/code&gt; in the controller doesn’t find engine helpers.&lt;/p&gt;


	&lt;p&gt;Within the engine’s &lt;code&gt;init.rb&lt;/code&gt;, he hooked his engine’s &lt;code&gt;AnnouncementsHelper&lt;/code&gt; into the app’s &lt;code&gt;ApplicationHelper&lt;/code&gt; like so:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;config.to_prepare &lt;span class="r"&gt;do&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="co"&gt;ApplicationController&lt;/span&gt;.helper(&lt;span class="co"&gt;AnnouncementsHelper&lt;/span&gt;)&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Note that any code that extends classes from the application (such as &lt;code&gt;ApplicationController&lt;/code&gt;) must be wrapped in a &lt;code&gt;to_prepare&lt;/code&gt; block.&lt;/p&gt;


	&lt;p&gt;This is because &lt;code&gt;ApplicationController&lt;/code&gt; gets reloaded before each request during development. Without this block, only the first request would see the &lt;code&gt;AnnouncementsHelper&lt;/code&gt; methods.&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/4/23/tips-for-writing-your-own-rails-engine</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Dan Croak</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-04-22:8154</id>
    <published>2009-04-22T14:00:00Z</published>
    <updated>2009-04-22T22:57:01Z</updated>
    <category term="Development" />
    <category term="Technology" />
    <category term="email" />
    <category term="password" />
    <category term="rails 2.3" />
    <category term="rails authentication" />
    <category term="rails engine" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/Kc-qp_rf3yE/clearance-is-a-rails-engine" rel="alternate" type="text/html" />
    <title>Clearance is a Rails engine</title>
<content type="html">
            &lt;p&gt;Clearance is now a Rails engine… &lt;span class="caps"&gt;BLAOW&lt;/span&gt;!&lt;/p&gt;


&lt;div&gt;&amp;lt;object height="344" width="425"&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;param&gt;&amp;lt;/param&gt;&amp;lt;embed src="http://www.youtube.com/v/21OH0wlkfbc&amp;amp;#38;hl=en&amp;amp;#38;fs=1" height="344" width="425"&gt;&amp;lt;/embed&gt;&amp;lt;/object&gt;&lt;/div&gt;

	&lt;h3&gt;Why&lt;/h3&gt;


	&lt;p&gt;Clearance has served us well for many months. Our only complaints were shared by others:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://twitter.com/hasmanyjosh/status/1243860761"&gt;lots of includes&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://giantrobots.thoughtbot.com/2009/2/9/clearance-rails-authentication-for-developers-who-write-tests#comment--613675058"&gt;too much generated code&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;too many tests to maintain&lt;/li&gt;
		&lt;li&gt;sometimes awkward to override functionality&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;With the re-institution of Rails engines in Rails 2.3, we decided to convert Clearance to engine. The process was relatively painless, the code is far cleaner, and we think we were able to scratch all our itches.&lt;/p&gt;


	&lt;h3&gt;Philosophy&lt;/h3&gt;


	&lt;p&gt;We &lt;strong&gt;highly recommend&lt;/strong&gt; that you use the &lt;a href="http://cukes.info"&gt;Cucumber&lt;/a&gt; features that come with Clearance to test the integration of the engine with your app:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;script/generate clearance_features&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;You no longer run Clearance’s generated Shoulda &amp; Factory Girl tests within your test suite. That code is unit tested internally. Use the Cucumber features to test integration. If and when you override functionality, write your own unit tests.&lt;/p&gt;


	&lt;p&gt;Read &lt;a href="http://giantrobots.thoughtbot.com/2009/2/20/mixing-cucumber-with-test-unit"&gt;Mixing Cucumber with Test::Unit/Shoulda&lt;/a&gt; if you’re getting started with Cucumber and not using RSpec.&lt;/p&gt;


	&lt;h3&gt;Overriding&lt;/h3&gt;


	&lt;p&gt;We haven’t and probably won’t ever move Clearance beyond email and password authentication, despite frequent requests. We’re focused on “clean code that works” for the baseline authentication we’ve written over and over again for clients.&lt;/p&gt;


	&lt;p&gt;A &lt;strong&gt;huge&lt;/strong&gt; part of “clean code that works” means that overriding Clearance needs to be painless. The change to an engine helps achieve that goal.&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;7&lt;tt&gt;
&lt;/tt&gt;8&lt;tt&gt;
&lt;/tt&gt;9&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;UsersController&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;Clearance&lt;/span&gt;::&lt;span class="co"&gt;UsersController&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;def&lt;/span&gt; &lt;span class="fu"&gt;edit&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;    ...&lt;tt&gt;
&lt;/tt&gt;  &lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="co"&gt;ActionController&lt;/span&gt;::&lt;span class="co"&gt;Routing&lt;/span&gt;::&lt;span class="co"&gt;Routes&lt;/span&gt;.draw &lt;span class="r"&gt;do&lt;/span&gt; |map|&lt;tt&gt;
&lt;/tt&gt;  map.resources &lt;span class="sy"&gt;:users&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;That’s it.&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;Write your tests for whatever action you want to add or override.&lt;/li&gt;
		&lt;li&gt;Subclass one of Clearance’s controllers (&lt;code&gt;Users&lt;/code&gt;, &lt;code&gt;Sessions&lt;/code&gt;, &lt;code&gt;Passwords&lt;/code&gt;, and &lt;code&gt;Confirmations&lt;/code&gt;).&lt;/li&gt;
		&lt;li&gt;Update your routes (by default, the routes will point to the namespaced Clearance controllers).&lt;/li&gt;
	&lt;/ul&gt;


	&lt;h3&gt;The Royal Library of Alexandria&lt;/h3&gt;


	&lt;p&gt;All knowledge pertaining to Clearance can be found on its &lt;a href="http://wiki.github.com/thoughtbot/clearance"&gt;Github wiki&lt;/a&gt;, where you’ll find such articles as:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://wiki.github.com/thoughtbot/clearance/upgrading-to-rails-engine"&gt;Upgrading to Rails engine&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://wiki.github.com/thoughtbot/clearance/organization"&gt;Organization&lt;/a&gt; of modules, routes, &amp; flashes&lt;/li&gt;
		&lt;li&gt;Extending Clearance with &lt;a href="http://wiki.github.com/thoughtbot/clearance/sign-up-sign-in-with-user-name"&gt;usernames&lt;/a&gt;, &lt;a href="http://wiki.github.com/thoughtbot/clearance/admin"&gt;admins&lt;/a&gt;, or &lt;a href="http://wiki.github.com/thoughtbot/clearance/invites-and-clearance"&gt;invite codes&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;.. and much more.&lt;/p&gt;


	&lt;p&gt;Enjoy!&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/4/22/clearance-is-a-rails-engine</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Dan Croak</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-04-17:8113</id>
    <published>2009-04-17T14:23:00Z</published>
    <updated>2009-04-17T14:23:36Z</updated>
    <category term="Development" />
    <category term="Technology" />
    <category term="open source" />
    <category term="rails source code" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/S1TMPUBG2dg/klang-strongbox" rel="alternate" type="text/html" />
    <title>Klang &amp; Strongbox</title>
<content type="html">
            &lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2008/12/16/icon-training.gif" /&gt;We’ve been running &lt;a href="http://thoughtbot.com/services/training"&gt;Ruby on Rails training&lt;/a&gt; classes since September. Classes are running monthly:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;a href="http://thoughtbot.com/services/training/beginning-ruby-on-rails-boston"&gt;Beginning Ruby on Rails&lt;/a&gt;&lt;/li&gt;
		&lt;li&gt;&lt;a href="http://thoughtbot.com/services/training/advanced-ruby-on-rails-boston"&gt;Advanced Ruby on Rails&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Since graduating, our alumni have been building some great stuff. Here’s a selection of their public work.&lt;/p&gt;


	&lt;h2&gt;Klang&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://klang.org"&gt;Klang&lt;/a&gt; is a small record label. Alumni &lt;a href="http://www.viget.com/about/team/mcornick"&gt;Mark Cornick&lt;/a&gt; built their Rails app.&lt;/p&gt;


&lt;div&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/4/16/Picture_2.png" width="500px" /&gt;&lt;/div&gt;

	&lt;p&gt;From Mark:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;It combines a blog-style news section, a product catalog w/ a (not fully automated) shopping cart, a show listing, and some other features. Behind the scenes, there’s &lt;a href="http://github.com/thoughtbot/shoulda"&gt;Shoulda&lt;/a&gt; and &lt;a href="http://github.com/thoughtbot/factory_girl"&gt;factory_girl&lt;/a&gt; for testing, and I recently replaced file_column with &lt;a href="http://github.com/thoughtbot/paperclip"&gt;Paperclip&lt;/a&gt; and restful_authentication with &lt;a href="http://github.com/thoughtbot/clearance"&gt;Clearance&lt;/a&gt;.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;If you want to see a well-written, well-tested Rails app’s full source code, Mark has has put the &lt;a href="http://github.com/mcornick/klang"&gt;full source code on github&lt;/a&gt;. Very cool! The question, “where can I see real-world Rails app source code” often comes up on Ruby mailing lists. Point them to Klang.&lt;/p&gt;


	&lt;p&gt;As if that wasn’t enough, Mark has made &lt;a href="http://runcoderun.com/mcornick/klang"&gt;Klang’s RunCodeRun builds&lt;/a&gt; public. For those unfamiliar with &lt;a href="http://runcoderun.com"&gt;RunCodeRun&lt;/a&gt;, it’s a hosted &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;Continuous Integration&lt;/a&gt; service from &lt;a href="http://thinkrelevance.com/"&gt;Relevance&lt;/a&gt;.&lt;/p&gt;


	&lt;h2&gt;Strongbox&lt;/h2&gt;


	&lt;p&gt;&lt;a href="http://github.com/spikex/strongbox"&gt;Strongbox&lt;/a&gt; is Ruby gem by Spike Ilacqua that provides Public Key Encryption for ActiveRecord.&lt;/p&gt;


	&lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/4/16/great_train_robbery.JPG" /&gt;From Spike:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;The idea isn’t new, I originally did this is Perl five or so years ago,  and &lt;a href="http://stuff-things.net/2008/02/05/encrypting-lots-of-sensitive-data-with-ruby-on-rails/"&gt;the most popular post on my blog&lt;/a&gt; is a how-to I wrote a year ago.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;blockquote&gt;
		&lt;p&gt;I wrote a gem for internal use at the same time I wrote the post, but I never published it.  My testing was weak, and I didn’t want to put it out in the world without better coverage.   Enter Advanced Rails Training.  The class really helped me get my head around testing and &lt;span class="caps"&gt;TDD&lt;/span&gt;, and that’s how I’ve been approaching all of my projects. I re-built the gem using &lt;span class="caps"&gt;TDD&lt;/span&gt; and posted it to Github.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;This is a cool idea and has a nice &lt;span class="caps"&gt;API&lt;/span&gt;:&lt;/p&gt;


&lt;table class="CodeRay"&gt;&lt;tr&gt;
  &lt;td title="click to toggle" class="line_numbers"&gt;&lt;pre&gt;1&lt;tt&gt;
&lt;/tt&gt;2&lt;tt&gt;
&lt;/tt&gt;3&lt;tt&gt;
&lt;/tt&gt;4&lt;tt&gt;
&lt;/tt&gt;&lt;strong&gt;5&lt;/strong&gt;&lt;tt&gt;
&lt;/tt&gt;6&lt;tt&gt;
&lt;/tt&gt;&lt;/pre&gt;&lt;/td&gt;
  &lt;td class="code"&gt;&lt;pre&gt;&lt;span class="r"&gt;class&lt;/span&gt; &lt;span class="cl"&gt;User&lt;/span&gt; &amp;lt; &lt;span class="co"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="co"&gt;Base&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;  encrypt_with_public_key &lt;span class="sy"&gt;:secret&lt;/span&gt;,&lt;tt&gt;
&lt;/tt&gt;    &lt;span class="sy"&gt;:key_pair&lt;/span&gt; =&amp;gt; &lt;span class="co"&gt;File&lt;/span&gt;.join(&lt;span class="co"&gt;RAILS_ROOT&lt;/span&gt;,&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;config&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;,&lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;keypair.pem&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;),&lt;tt&gt;
&lt;/tt&gt;&lt;span class="r"&gt;end&lt;/span&gt;&lt;tt&gt;
&lt;/tt&gt;&lt;tt&gt;
&lt;/tt&gt;user.secret.decrypt &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;


	&lt;p&gt;Great job, Mark and Spike! We can’t wait to see what the growing ranks of alumni make next.&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/4/17/klang-strongbox</feedburner:origLink></entry>
  <entry xml:base="http://giantrobots.thoughtbot.com/">
    <author>
      <name>Matt Jankowski</name>
    </author>
    <id>tag:giantrobots.thoughtbot.com,2009-04-15:8016</id>
    <published>2009-04-15T15:38:00Z</published>
    <updated>2009-04-15T15:42:35Z</updated>
    <category term="Development" />
    <link href="http://feedproxy.google.com/~r/GiantRobotsSmashingIntoOtherGiantRobots/~3/RRU954j2jMU/rails-2-3-2-upgrade-gotchas" rel="alternate" type="text/html" />
    <title>Rails 2.3.2 upgrade gotchas</title>
<content type="html">
            &lt;p&gt;With the &lt;a href="http://weblog.rubyonrails.org/2009/3/16/rails-2-3-templates-engines-rack-metal-much-more"&gt;latest stable release of rails&lt;/a&gt; out the door for about a month, we’ve had a chance to upgrade the bulk of the applications we maintain to 2.3.2.1.  The &lt;a href="http://guides.rubyonrails.org/2_3_release_notes.html"&gt;rails 2.3 release notes&lt;/a&gt; were a &lt;span class="caps"&gt;HUGE&lt;/span&gt; help during this upgrade.  Thanks to the Mike Gunderloy for compiling that document.&lt;/p&gt;


&lt;p&gt;&lt;img src="http://giantrobots.thoughtbot.com/assets/2009/4/15/dinosaur-images-040-resize.jpg.jpeg" alt="" /&gt;&lt;/p&gt;

	&lt;p&gt;Here are some “gotchas”, aka issues, aka roadblocks to Strategic Enterprise Adoption that we discovered while upgrading some of them.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Upgrade Hoptoad&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: `const_missing’: uninitialized constant &lt;span class="caps"&gt;CGI&lt;/span&gt;::Session (NameError)&lt;/p&gt;


	&lt;p&gt;Solution: &lt;a href="http://www.hoptoadapp.com"&gt;Hoptoad Notifier&lt;/a&gt; plugin needs to be updated.&lt;/p&gt;


&lt;pre&gt;ruby script/plugin install --force git://github.com/thoughtbot/hoptoad_notifier.git&lt;/pre&gt;

	&lt;p&gt;&lt;strong&gt;Rename application controller&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: `load_missing_constant’: uninitialized constant ApplicationController (NameError)&lt;/p&gt;


	&lt;p&gt;Solution: You need to rename application.rb to application_controller.rb&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;&lt;span class="caps"&gt;CGI&lt;/span&gt;::Cookie&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem:  &lt;code&gt;@request.cookies["name"] = CGI::Cookie.new("name", "value")&lt;/code&gt; sets the cookie to [“value”] instead of “value”.&lt;/p&gt;


	&lt;p&gt;Solution:  You no longer need to set the cookie to a &lt;code&gt;CGI::Cookie&lt;/code&gt; instance.  Just set it to the string directly:  &lt;code&gt;@request.cookies["name"] = "value"&lt;/code&gt;&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Transactional Fixtures&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: undefined method `use_transactional_fixtures=’ for Test::Unit::TestCase:Class (NoMethodError)&lt;/p&gt;


	&lt;p&gt;Solution: In your test/test_helper.rb file, you need to rename ‘Test::Unit::TestCase’ to ‘ActiveSupport::TestCase’ to set these options.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Routing tests&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: NoMethodError: undefined method `assert_recognizes’ for #&amp;lt;RoutesTest:0×22058f8&amp;gt;&lt;/p&gt;


	&lt;p&gt;Solution: Are you testing your routes in a unit test with a class of ActiveSupport::TestCase?  The routing assertions are only included in ActionController::TestCase now, so change the test class to use that instead.&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Count through associations&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: errors on a #count that goes through a named_scope on a has_many :through.  This used to successfully proxy through and run a successful &lt;span class="caps"&gt;SQL COUNT&lt;/span&gt; query.  Now there’s &lt;a href="http://rails.lighthouseapp.com/projects/8994/tickets/2189-count-breaks-sqlite-has_many-through-association-collection-with-named-scope#ticket-2189-10"&gt;all this&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;Solution: not sure yet, maybe use the file at the end of that ticket?&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Upgrade rake&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: when you deploy to staging or production, you get an error about an undefined ‘reenable’ method on Rake::Task.&lt;/p&gt;


	&lt;p&gt;Solution: This method was introduced in rake 0.8.2, but not actually used by rails prior to the 2.3 release.  You need to update rake to a version newer than 0.8.2 on your servers (0.8.4 is latest stable as of now).&lt;/p&gt;


	&lt;p&gt;&lt;strong&gt;Upgrade rubygems&lt;/strong&gt;&lt;/p&gt;


	&lt;p&gt;Problem: When deploying you get an “undefined method `ruby_version’ for Gem:Module” error.&lt;/p&gt;


	&lt;p&gt;Solution:  Upgrade rubygems to the latest stable version (1.3.1 at the time of this post).&lt;/p&gt;
          </content>  <feedburner:origLink>http://giantrobots.thoughtbot.com/2009/4/15/rails-2-3-2-upgrade-gotchas</feedburner:origLink></entry>
</feed>
