<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>Alloy Code - Home</title>
  <id>tag:www.alloycode.com,2008:mephisto/</id>
  <generator uri="http://mephistoblog.com" version="0.7.3">Mephisto Noh-Varr</generator>
  <link href="http://www.alloycode.com/feed/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.alloycode.com/" rel="alternate" type="text/html"/>
  <updated>2008-06-01T14:15:54Z</updated>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-06-01:66</id>
    <published>2008-06-01T14:03:00Z</published>
    <updated>2008-06-01T14:15:54Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/6/1/rails-2-1-now-available" rel="alternate" type="text/html"/>
    <title>Rails 2.1 Now Available</title>
<content type="html">
            &lt;p&gt;Coinciding nicely with the conclusion of &lt;a href=&quot;http://en.oreilly.com/rails2008/public/content/home&quot;&gt;Railsconf 2008&lt;/a&gt;, it would appear that Rails 2.1 &lt;a href=&quot;http://weblog.rubyonrails.com/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc&quot;&gt;has been released&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The feature I'm most excited about?  &lt;a href=&quot;http://ryandaigle.com/articles/2008/1/25/what-s-new-in-edge-rails-easier-timezones&quot;&gt;Native Timezone support&lt;/a&gt;.  June 2008 marks my two year anniversary of working with Rails, and of all the projects I've taken on, the majority have required working with time zones.  This is a most welcome change indeed.&lt;/p&gt;

&lt;p&gt;I'd just like to add my voice to the chorus saying 'Great Job!' to the Rails core team and the 1,400 other contributors that have all added to Rails in the past six months.   &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-05-09:65</id>
    <published>2008-05-09T15:16:00Z</published>
    <updated>2008-05-09T15:16:52Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/5/9/irb-command-history-in-time-machine" rel="alternate" type="text/html"/>
    <title>IRb Command History in Time Machine</title>
<content type="html">
            &lt;p&gt;&lt;img src=&quot;http://www.alloycode.com/assets/2008/5/9/Picture_5.png&quot; alt=&quot;TIme Machine&quot; /&gt;Of the 300 new features in Leopard (Mac OS 10.5), Time Machine may be the one that excites me the most.  I've already used to to repair applications after failed updates, pull back browser history items from two months ago, and restore emails that I had inadvertently flushed.  &lt;/p&gt;

&lt;p&gt;Yesterday, I found a new use for Time Machine: reviving IRb command history.&lt;/p&gt;

&lt;p&gt;Over at &lt;a href=&quot;http://edufire.com&quot;&gt;eduFire&lt;/a&gt;, we've been working on converting user profile pictures from file system store to S3 backed storage.  Since we're using the &lt;code&gt;attachment_fu&lt;/code&gt; plugin, it seemed that the easiest way would be to just create a new instance of the user profile picture and feed in the path to the file.&lt;/p&gt;

&lt;p&gt;While using &lt;code&gt;attachment_fu&lt;/code&gt; in a controller is beautifully simple, requiring just an &lt;code&gt;uploaded_data&lt;/code&gt; parameter, manipulating files through &lt;code&gt;script/console&lt;/code&gt; is a bit more difficult.  I knew we had wrestled with this back in February, when we changed the default thumbnail resolutions, and had to reprocess everyone's photos.  What I had failed to do back then was document &lt;em&gt;how&lt;/em&gt; we actually achieved it.&lt;/p&gt;

&lt;p&gt;I have my IRb history logging to &lt;code&gt;~/.irb_history&lt;/code&gt;, but with only 500 lines of scrollback, I knew that there was no chance an entry from three months ago had survived.  My first attempt to view the file in Time Machine was unsuccessful, as I couldn't seem to figure out how to get Time Machine to display dot-files.&lt;/p&gt;

&lt;p&gt;However, the Time Machine archive is browsable in Terminal; after finding the path to the relevant backup (which looked something like this: &lt;code&gt;/Volumes/Time Machine Drive/Backups.backupdb/AlloyCode/2008-03-03-000650/Macintosh HD/Users/jared&lt;/code&gt;), I was able to open the &lt;code&gt;.irb_history&lt;/code&gt; file in TextMate and find the command I had lost.&lt;/p&gt;

&lt;p&gt;For those who might need to do a similar operation in the future, here's how to recreate a file attachment in script/console:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;Avatar.create(:filename =&amp;gt; filename, :content_type =&amp;gt; content_type, :temp_path =&amp;gt; temp_path)&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;In the above example, &lt;code&gt;filename&lt;/code&gt; corresponds to the name to save the attachment as on the server, &lt;code&gt;content_type&lt;/code&gt; is the MIME type, and &lt;code&gt;temp_path&lt;/code&gt; is the full path to the actual asset.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-04-26:51</id>
    <published>2008-04-26T15:56:00Z</published>
    <updated>2008-04-26T15:57:55Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/4/26/another-passenger-on-the-mod_rails" rel="alternate" type="text/html"/>
    <title>Another Passenger on the mod_rails</title>
<content type="html">
            &lt;p&gt;A lot has been said about running Rails applications on shared hosting, most visibly in these two articles by &lt;a href=&quot;http://loudthinking.com/posts/21-the-deal-with-shared-hosts&quot;&gt;David Heinemeier Hansson&lt;/a&gt; and &lt;a href=&quot;http://blog.dreamhost.com/2008/01/07/how-ruby-on-rails-could-be-much-better/&quot;&gt;Dallas Kashuba&lt;/a&gt; (on the DreamHost blog).  For the past eight months, Alloy Code and &lt;a href=&quot;http://yourgarageonline.com&quot;&gt;Your Garage Online&lt;/a&gt; have been running on a single 256mb slice from &lt;a href=&quot;http://slicehost.com&quot;&gt;Slicehost&lt;/a&gt;, and while it was possible to get the two sites to happily co-exist, I've always regarded it as something of a delicate house of cards, just waiting for a gust of wind or slammed door in a neighboring apartment to knock the whole stack down.  Well, two weeks ago, I made a serious change in back-end configuration, and I couldn't be happier.  Indulge me for a moment, because I feel that a little history is appropriate&amp;hellip;&lt;/p&gt;

&lt;p&gt;Initially, the slice was configured with Apache 2.2 acting as a proxy for two mongrel clusters.  The resources of the slice itself allowed me to run two mongrels for the blog, and three for Your Garage Online.  Since the majority of the blog's content is cached static pages, two mongrels seemed like plenty, and only suffered a slight delay in attempting to access the admin interface, or other dynamic content.  &lt;/p&gt;

&lt;p&gt;Then I came across &lt;a href=&quot;http://brainspl.at/articles/2006/08/23/nginx-my-new-favorite-front-end-for-mongrel-cluster&quot;&gt;Ezra's&lt;/a&gt; article on nginx, and I invested the better part of a weekend switching from a pure Apache/Mongrel setup, to something of a strange hybrid.  Since nginx wouldn't honor SVN webdav connections properly, I had to keep an apache instance handy, but restricted to listening on a high-numbered port, with nginx forwarding requests intended for my SVN repositories back into Apache.  Meanwhile, nginx had two other listeners set up, one forwarding Alloy Code traffic to the blog's mongrel cluster, and one forwarding Your Garage Online traffic to the other mongrel cluster.  &lt;/p&gt;

&lt;p&gt;A few months ago, I heard about Thin while listening to the &lt;a href=&quot;http://railsenvy.com&quot;&gt;Rails Envy Podcast&lt;/a&gt;, and the idea of using Unix sockets instead of TCP to forward the proxy requests really appealed to me.  Unfortunately, even though I had upgraded my slice's copy of Ruby to 1.8.6, I was never able to get the Thin gem to install.  Later, I discovered it was because my RubyGems installation was linked against the older, 1.8.5 version of the ruby binary.  I never did find a good way to switch the &lt;code&gt;gem&lt;/code&gt; command's installed ruby version, I had to reinstall RubyGems from scratch using the 1.8.6 binary to call the setup.rb file.&lt;/p&gt;

&lt;p&gt;So, when &lt;a href=&quot;http://modrails.com&quot;&gt;Passenger&lt;/a&gt; came out, the configuration-tweaker in me was &lt;em&gt;very&lt;/em&gt; excited to give it a try.  Once again, I set aside the better part of a weekend to get the installation going.  After sorting out the gems issue above, and recompiling Apache to include prefork support, I was ready to roll.  &lt;/p&gt;

&lt;p&gt;The installation instructions provided were enough to get me 90% of the way there.  I had overlooked the fact that, eight months ago, I told Apache to only listen for connections on port 8010 (part of the nginx-svn debacle).  And, it turns out that when running two rails applications on a single host, with a single IP address, I needed to provide a little extra context to make certain the static content was handled properly.  &lt;/p&gt;

&lt;p&gt;Since the hostname of the box itself is alloycode.com, the setup for the blog is as sparse as the Passenger sample:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
    ServerName alloycode.com
    DocumentRoot /path/to/blog/public
  &amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Setting up Your Garage Online was a little tricker.  My first attempt was just to mirror the same code as above, but with the proper &lt;code&gt;ServerName&lt;/code&gt; and &lt;code&gt;DocumentRoot&lt;/code&gt; settings.  Unfortunately, that meant that while the Rails stack did load, and process the requests properly, none of the stylesheets, images, javascrtips, or other static assets could be loaded.  After carefully investigating each of the options in the Passenger documentation, I managed to put together this VirtualHost definition that seemed to do the trick:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;VirtualHost *:80&amp;gt;
     ServerName yourgarageonline.com
     ServerAlias www.yourgarageonline.com        
     DocumentRoot /path/to/ygo/public
     &amp;lt;Directory &amp;quot;/path/to/ygo/public&amp;quot;&amp;gt;
         Options FollowSymLinks
         AllowOverride None
         Order allow,deny
         Allow from all
     &amp;lt;/Directory&amp;gt;
     RailsBaseURI /
  &amp;lt;/VirtualHost&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And like that, it was as if a switch was flipped, and everything was working 100%.  It's now been two weeks since I put Passenger on that slice, and I haven't had any outages or runaway memory problems, and I no longer have to worry about my web server and my mongrel cluster getting out of sync, resulting in dreaded 503 Service Unavailable errors.  &lt;/p&gt;

&lt;p&gt;Kudos to the &lt;a href=&quot;http://modrails.com&quot;&gt;Phusion&lt;/a&gt; folks, this is one incredible release.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-02-10:49</id>
    <published>2008-02-10T23:52:00Z</published>
    <updated>2008-03-02T00:40:29Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/2/10/heroku-hijinks" rel="alternate" type="text/html"/>
    <title>Heroku Hijinks</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://heroku.com&quot;&gt;Heroku&lt;/a&gt;, a &lt;a href=&quot;http://ycombinator.com/&quot;&gt;Y Combinator&lt;/a&gt; funded startup, has been making headlines lately!  Mentions on the official &lt;a href=&quot;http://weblog.rubyonrails.org/2008/2/7/write-rails-apps-in-your-browser&quot;&gt;Ruby on Rails blog&lt;/a&gt;, the &lt;a href=&quot;http://podcast.rubyonrails.org/programs/1/episodes/heroku&quot;&gt;Ruby on Rails Podcast&lt;/a&gt;, and even an article on &lt;a href=&quot;http://www.techcrunch.com/2008/02/07/heroku-lifts-ruby-on-rails-development-to-the-cloud/trackback/&quot;&gt;TechCrunch&lt;/a&gt; outlining some of the upcoming features.  Personally, I've been using it since late last year, and I've found it to be immensely useful in a couple of situations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 1:&lt;/strong&gt; While interviewing for my &lt;a href=&quot;http://edurev.com&quot;&gt;current job&lt;/a&gt;, I wanted to show my interviewers the application Keith and I had developed for the Rails Rumble.  Thanks to some trademark issues and a certain corporation whose devices have become synonymous for copiers, the document collaboration application didn't have an online presence.  Rather than attempt to put it back online with my current shared hosting (already stretched to the limit by this blog and the YGO application) or secure new shared hosting, instead I prepared to zip up the entire application and upload it to my Heroku account.  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first thing I had to do was unpack the gems used by the application, such as &lt;code&gt;attachment_fu&lt;/code&gt; into my /vendor directory, and make sure I added them to my &lt;code&gt;config/environment.rb&lt;/code&gt; load path.  &lt;/li&gt;
&lt;li&gt;Secondly, I removed all my existing log files... no need to push an additional 300mb of data online!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After zipping the app and uploading it, I just needed to click the 'migrate' button inside the Heroku editor window, and I was in business.  By virtue of putting the app online in a private state, I could ensure that only my interviewers were able to see it, and I was able to take it back offline once the interview process had concluded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scenario 2:&lt;/strong&gt; In doing some freelance work on a contract tracking app, I wanted to show &lt;a href=&quot;http://catalystgamelabs.com&quot;&gt;my client&lt;/a&gt; a live preview of the progress I was making, and to get some early feedback on some of the workflow.  Again, rather than expose the whole application live through my existing hosting, I again created a zipped version of the application and added it to Heroku.&lt;/p&gt;

&lt;p&gt;This time, I was able to show him the current 'snapshot' of the application, and instantly incorporate minor tweaks without even needing to reload a mongrel instance or re-upload any files.  Small details, like the text on a form label or the size of an element could easily be adjusted on the fly, in accordance with the client's wishes; then, those changes were easily mirrored back down to my local copy to continue development.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;All in all,&lt;/em&gt; I'm very impressed with Heroku.  While I don't make extensive use of the in-browser editor, the few times I've had to make tweaks to a running instance, it's been very easy to do so right in the browser.  Plus, having a browser based interface to my favorite ruby tool, &lt;code&gt;script/console&lt;/code&gt;, has been incredibly useful.&lt;/p&gt;

&lt;p&gt;Lastly, I think Heroku illustrates an excellent usage of Amazon Web Services as part of a business model, particularly in being able to make using EC2 easily available to the end user, along with an easy way to pass along the associated costs to that user.  I'll be very excited to see where the future takes them.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2008-01-11:44</id>
    <published>2008-01-11T19:28:00Z</published>
    <updated>2008-01-11T19:31:00Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2008/1/11/learning-rspec-part-ii" rel="alternate" type="text/html"/>
    <title>Learning RSpec, Part II</title>
<content type="html">
            &lt;p&gt;In the &lt;a href=&quot;/2007/12/30/learning-rspec&quot;&gt;first entry&lt;/a&gt;, one of the issues I addressed was stubbing a response to an HTTP-Basic Authentication scheme.  To get my spec to pass, I stubbed the entire &lt;code&gt;authenticate&lt;/code&gt; method which I had written.  While this approach was successful, it left me with a hole in my code coverage:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://www.alloycode.com/assets/2008/1/11/missing_coverage_1.png&quot; height=&quot;97&quot; alt=&quot;RCov Coverage&quot; width=&quot;420&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now that I knew my controllers' actions were being tested, I needed a good way to test the authenticate method itself, to ensure that failed requests were not being let through.  A quick glance in the Rails source gave me some clues to implementation.&lt;/p&gt;

&lt;p&gt;Since the credentials are sent (encoded) in the HTTP header, the first thing I needed to do was inject those credentials into the header before the request was processed.  Rails core (using Test::Unit) uses the following convenience method in &lt;code&gt;/actionpack/test/controller/http_authentication_test.rb&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def set_headers(value = @credentials, name = 'HTTP_AUTHORIZATION')
      @controller.request.env[name] = value
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The encoded credentials are passed in and assigned to the request environment.  Accomplishing this in RSpec wasn't much different.  First, we construct a set of encoded credentials, then we assign them to the environment variable 'HTTP_AUTHORIZATION'.  Note that in the RSpec code below, we don't call &lt;code&gt;@controller.request.env&lt;/code&gt;, but simply &lt;code&gt;request.env&lt;/code&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;before(:each) do 
    @credentials = ActionController::HttpAuthentication::Basic.encode_credentials(&amp;quot;david&amp;quot;, &amp;quot;clearly_false&amp;quot;)
    request.env['HTTP_AUTHORIZATION'] = @credentials
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This allowed me to create a series of tests to check that a user providing invalid credentials was not being allowed into the protected areas of the site.  &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it &amp;quot;should fail with invalid credentials&amp;quot; do
      get :index
      response.should_not be_success
      response.headers[&amp;quot;Status&amp;quot;].should =~ /401/
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Two fairly simple expectations, when attempting to access a resource using invalid credentials, the response should not be a success, and the status code should match 401 (Unauthorized).&lt;/p&gt;

&lt;p&gt;RSpec is definitely growing on me, and I've noticed some BDD disciplines starting to creep into my approach to testing with Test::Unit in my day job.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-12-30:41</id>
    <published>2007-12-30T21:59:00Z</published>
    <updated>2007-12-30T21:59:30Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/12/30/learning-rspec" rel="alternate" type="text/html"/>
    <title>Learning RSpec</title>
<content type="html">
            &lt;p&gt;&lt;em&gt;The end of 2007 has brought about some exciting changes for me, most notably a new job with &lt;a href=&quot;http://edurev.com/&quot;&gt;Education Revolution&lt;/a&gt;.  To try and ease the transition during a stressful holiday season, I gave myself a week off between jobs, which left me with a bit of unexpected time on my hands between Christmas and New Year's.  I decided to make the most of my time off and try to learn &lt;a href=&quot;http://rspec.info&quot;&gt;RSpec&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;RSpec is quickly becoming a darling among some of the visionaries in the Rails world.  With the release of RSpec 1.1, which brings easy integration between Test::Unit style testing and Behavior Driven Development using RSpec, it seemed prudent to try it on myself and see how it fits.&lt;/p&gt;

&lt;p&gt;On the whole I really like the idea of specifying behaviors instead of assertions, especially when coupled with doing some design-driven development.  As a developer, having both a clear set of expected behaviors and a set of slides which show the application in a near-finished state, it removes a lot of the guesswork which had been plaguing me on previous projects.  Also, hearing &lt;a href=&quot;http://basement.thewilliams.ws/&quot;&gt;Adam Williams&lt;/a&gt; and &lt;a href=&quot;http://wiseheartdesign.com&quot;&gt;John Long&lt;/a&gt; talk at November's Raleigh.rb meetup about doing top-down testing (starting with integration tests, then drilling down to functional and unit tests merely to handle edge cases) has turned my opinion of Integration tests on it's head.&lt;/p&gt;

&lt;p&gt;Having come from a metaprogramming-driven Test::Unit background using Mike Clark's TestRig framework, RSpec &lt;em&gt;felt&lt;/em&gt; like a lot more testing code.  And indeed, my &lt;code&gt;rake stats&lt;/code&gt; seems to support that, showing a 1:2.8 ratio for my training project.  Finding help with RSpec has been tricky, though.  There are some really great contrived examples on the RSpec homepage, but I had trouble finding more information on how to deal with presenters, nested resources, and HTTP Basic authentication.  I want to show off two solutions that I cobbled together out of solutions found online.&lt;/p&gt;

&lt;p&gt;The first problem I encountered was in dealing with the &lt;code&gt;save!&lt;/code&gt; method in ActiveRecord.  My controllers typically use the &lt;code&gt;save!&lt;/code&gt; coupled with a rescue statement for &lt;code&gt;ActiveRecord::RecordInvalid&lt;/code&gt;, like so:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class WidgetsController &amp;lt; ApplicationController

        def create
            @widget = Widget.new(params[:widget])
            @widget.save!
            respond_to do |format|
                format.html { redirect_to @widget }
            end
        rescue ActiveRecord::RecordInvalid =&amp;gt; e
            respond_to do |format|
                format.html { render :action =&amp;gt; 'edit' }
            end
        end

    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Most of the RSpec examples I had come across show something like this (excerpted from &lt;a href=&quot;http://www.elevatedrails.com/articles/2007/09/10/testing-controllers-with-rspec/&quot;&gt;Testing Controllers with RSpec&lt;/a&gt;):&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def do_create
    post :create, :menu_item=&amp;gt;{:name=&amp;gt;&amp;quot;value&amp;quot;}
  end

  it &amp;quot;should save the menu item&amp;quot; do
    @menu_item.should_receive(:save).and_return(false)
    do_create
  end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The problem being, using &lt;code&gt;save!&lt;/code&gt; doesn't return false on failure, it raises an exception.  Fortunately, the answer was available on the &lt;a href=&quot;http://www.nabble.com/Re%3A-Problems-with-raising-errors-on-a-mocked-object-p12047955.html&quot;&gt;RSpec-users mailing list&lt;/a&gt;.  Now my &lt;code&gt;widet_controller_spec.rb&lt;/code&gt; contains the following:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;it &amp;quot;should fail to save the widget&amp;quot; do
      @widget.should_receive(:save!).and_raise(ActiveRecord::RecordInvalid.new(@widget))
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The second major stoppage I encountered was dealing with HTTP Basic authentication.  The application I was building didn't require a huge complicated account/password structure, it just needed a few protected pages available to a single administrator.  &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class ApplicationController &amp;lt; ActionController::Base

        before_filter :authenticate

        def authenticate
          authenticate_or_request_with_http_basic do |username, password|
            username == 'jared' &amp;amp;&amp;amp; password == 'secret'
          end
        end
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Suddenly, all my controller specs for actions lying behind that &lt;code&gt;authenticate&lt;/code&gt; filter were failing.  The fix lies in stubbing out the method using the controller local variable in the spec.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;describe WidgetsController do

      describe &amp;quot;with successful admin login&amp;quot; do
        before(:each) do
          controller.stub!(:authenticate).and_return(true)
        end
            ...
        end
    end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Of course, I still need to come back and write an integration test which will address both the success and failure states of the authenticate method.&lt;/p&gt;

&lt;p&gt;All in all, I'm very impressed with RSpec, and I can see why it's picking up such a following.  I'm definitely going to play around with it further, but I'm not quite ready to say that I'm going to switch all my projects over; one important factor to consider is future code maintainability.  The pool of talented Rails developers is small enough to begin with, adding the further requirement of finding a Rails developer who is also versed in RSpec limits that result set even further.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-12-11:37</id>
    <published>2007-12-11T14:55:00Z</published>
    <updated>2007-12-11T15:02:43Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/12/11/advanced-yaml-fixtures-gotchas" rel="alternate" type="text/html"/>
    <title>Advanced YAML Fixtures Gotchas</title>
<content type="html">
            &lt;p&gt;I was very excited to use the new &lt;a href=&quot;http://api.rubyonrails.org/classes/Fixtures.html&quot;&gt;Advanced YAML Fixtures&lt;/a&gt; introduced in Rails 2.0, so I set about updating my code in an Edge Rails application I've been working on for the past year or so.  There are a few caveats in using the new fixture styles, though.  &lt;/p&gt;

&lt;p&gt;The Fixtures are introspective, so if you've overridden the default name of an association in your model, you'll need to use that new name in your fixture.  With the following code, &lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;class Worker &amp;lt; ActiveRecord::Base
  belongs_to :status, :class_name =&amp;gt; 'WorkerStatus', :foreign_key =&amp;gt; 'worker_status_id'
  ...
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The key for &lt;code&gt;worker_status:&lt;/code&gt; should actually just be &lt;code&gt;status:&lt;/code&gt; in the workers.yml fixture file.&lt;/p&gt;

&lt;p&gt;The larger problem I encountered was in using a mix of IDs and fixture record names.  I use a testing framework, &lt;em&gt;TestRig&lt;/em&gt;, which was written by Mike Clark and Dave Thomas for the &lt;a href=&quot;http://pragmaticstudio.com&quot;&gt;Pragmatic Studio&lt;/a&gt;.  The TestRig framework takes in ID parameters of fixtures in the database, and loads them accordingly.  This falls apart with the new &lt;code&gt;status: full_time&lt;/code&gt; style of declaring relationships in fixtures, because the former relies on a 'known' ID, and the new style generates a fairly random ID instead.  This leads to a bunch of broken relationships throughout the test suite.&lt;/p&gt;

&lt;p&gt;According to the API documentation, the generated ID is constant, so I could discover that ID and use it in the TestRig calls which require an integer key, but then I've essentially lost all benefit of using the Advanced YAML Fixtures, and added some crazy complexity to my tests as well.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-12-02:35</id>
    <published>2007-12-02T16:51:00Z</published>
    <updated>2007-12-02T16:54:24Z</updated>
    <link href="http://www.alloycode.com/2007/12/2/using-relational-data-responsibly" rel="alternate" type="text/html"/>
    <title>Using Relational Data Responsibly</title>
<content type="html">
            &lt;p&gt;Every Christmas, my father sends gift assortments from &lt;a href=&quot;http://www.swisscolony.com&quot;&gt;Swiss Colony&lt;/a&gt; to family members, friends, and former business associates.  Last month, he shared with me an interesting story about how Swiss Colony handles repeat customers; which he gave me permission to retell here, because I think it&#8217;s a great example of a non-technical company using modern technology effectively.&lt;/p&gt;

&lt;p&gt;He started out telling me about a woman who used to work for him 18 years ago, someone whom he has kept in touch with over the years, exchanging a few letters annually.  He knew that she had moved recently, but had not yet received her new mailing address.  However, when he received his most recent Swiss Colony catalog, he noticed that her address had been updated.  He was suitably impressed.&lt;/p&gt;

&lt;p&gt;One of my former jobs required me to send periodical mailings to a nationwide group of photojournalists, an activity that probably gave me more insight into business-based bulk mailing than any web application developer would ever care to have.  But, it did leave me with an answer as to how her information was likely updated.  It would seem that the company runs it&#8217;s entire recipient database through an automated service, such as &lt;em&gt;Verimove&lt;/em&gt;, in order to keep their mailing address data fresh.&lt;/p&gt;

&lt;p&gt;In addition to providing repeat customers with the list of all the recipients who had received gifts the previous year, they also include the previous year&#8217;s order for each recipient.  It&#8217;s a refreshing change of pace from those companies that vacuum up a great deal of information about their customers but then don&#8217;t turn it around and use it effectively.  Swiss Colony offers, even for it&#8217;s mail-order customers, the benefit of relational data.&lt;/p&gt;

&lt;p&gt;Taking this a step further for the world of web development, this sort of information can be ideal to use as part of a &#8216;hook&#8217; strategy to drive return traffic to an application.  Instead of just emailing existing users to tell them about new products or services you provide, offer them &lt;em&gt;value&lt;/em&gt; by doing a little bit of analysis on the relationships they already have in your systems, and making their experience more convenient.  &lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-11-13:27</id>
    <published>2007-11-13T21:06:00Z</published>
    <updated>2007-11-13T21:06:47Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/11/13/de-ascii-your-rails-logs" rel="alternate" type="text/html"/>
    <title>De-ASCII Your Rails Logs</title>
<content type="html">
            &lt;p&gt;Recently, I've been delving into some filter-related problems in one of my Rails applications.  This has required me to trap and review specific segments of my Rails log files.  As part of my initial stack setup when I begin a new project, I install the &lt;a href=&quot;http://svn.umesd.k12.or.us/plugins/query_analyzer/&quot;&gt;Query Analyzer&lt;/a&gt; and &lt;a href=&quot;https://terralien.devguard.com/svn/projects/plugins/query_trace/&quot;&gt;Query Trace&lt;/a&gt; plugins.  &lt;/p&gt;

&lt;p&gt;The upside is I get very detailed trace information for my application, pictured below:&lt;/p&gt;
&lt;img src=&quot;/assets/2007/11/13/colorful_log.png&quot; height=&quot;201&quot; alt=&quot;Log output&quot; width=&quot;311&quot; /&gt;

&lt;p&gt;The downside is, when these files are viewed with Textmate or Console, they wind up looking more like this:&lt;/p&gt;
&lt;pre&gt;
    Rendered events/_event (0.00036)  
      [4;35;1mSlot Load (0.000361)[0m   [0mSELECT * FROM 'slots' WHERE (slots.event_id = 23) [0m  
        [35;2mvendor/plugins/query_analyzer/lib/query_analyzer.rb:38:in 'select'[0m  
        [35;2mlib/association_extensions/chronological.rb:9:in 'first'[0m  
        [35;2mapp/models/event.rb:109:in 'begin_at'[0m  
        [35;2mapp/views/events/_event.html.erb:6:in '_run_erb_47app47views47events47_event46html46erb'[0m  
        [35;2mapp/views/events/index.html.erb:39:in '_run_erb_47app47views47events47index46html46erb'[0m
&lt;/pre&gt;

&lt;p&gt;Today's &quot;stretch the brain&quot; exercise centered around creating a Textmate command to clear out this unnecessary cruft.  For starters, I cloned the Text bundle's &quot;Remove Unprintable Characters in Document / Selection&quot; command.  It looks like the Textmate folks are using Perl to remove unprintable characters:  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;perl -pe 's/[^\t\n\x20-\xFF]|\x7F|\xC2[\x80-\x9F]//g'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I left all the settings unchanged:  &lt;br /&gt;
&lt;em&gt;Save&lt;/em&gt;: Nothing&lt;br /&gt;
&lt;em&gt;Input&lt;/em&gt;: Selected Text or Document&lt;br /&gt;
&lt;em&gt;Output&lt;/em&gt;: Replace Selected Text&lt;/p&gt;

&lt;p&gt;And edited the Perl regular expression to match each of the three possible variants of ASCII instruction:  &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;perl -pe 's/\[\d;?(\d+)?;?(\d)?m//g'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Success!  Now, with one keystroke, I can remove all that extra information from my log file, and get down to business.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-10-11:25</id>
    <published>2007-10-11T19:11:00Z</published>
    <updated>2007-10-11T19:53:06Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/10/11/when-things-get-saved" rel="alternate" type="text/html"/>
    <title>When Things Get Saved...</title>
<content type="html">
            &lt;p&gt;Having been excited about the upcoming Rails 2.0 release since I saw DHH speak in Portland at Railsconf, I've been starting all my new projects on Edge Rails in anticipation of the new version.&lt;/p&gt;

&lt;p&gt;While bringing one of my projects up-to-date with the Preview Release, I came across something relatively new that (to my mind) breaks the long-standing logic of &#8220;When Things Get Saved.&#8221;  &lt;/p&gt;

&lt;p&gt;I've been trying to keep with the &lt;a href=&quot;http://weblog.jamisbuck.org/2006/10/18/skinny-controller-fat-model&quot;&gt;Skinny Controller, Fat Model&lt;/a&gt; approach outlined by Jamis Buck, so I've moved the logic for creating my associated models out of the controller, and into the model.  &lt;/p&gt;

&lt;p&gt;My specific example deals with a semi-complex form, registering new users.  I needed to create a Company, a User, an Employee and some defaults, by simply prompting the user for a minimal amount of data (Company Name, First and Last name, email, password).  My Company model has the following associations:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;belongs_to :owner, :class_name =&amp;gt; &amp;quot;User&amp;quot;, :foreign_key =&amp;gt; &amp;quot;owner_id&amp;quot;
has_many :employees, :class_name =&amp;gt; &amp;quot;Employee&amp;quot;, :foreign_key =&amp;gt; &amp;quot;employer_id&amp;quot;
has_one :company_setting&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following snippet is taken from the Company model, this method instantiates a new company object, sets the owner, creates the first employee, assigns roles to the employee, and sets the default variables for the company's details.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def self.create_with_associations(options)
  returning new do |company|
    company.attributes = options[:company]
    company.create_owner(options[:user])
    employee = company.employees.create(:title =&amp;gt; &amp;quot;Owner&amp;quot;, :phone =&amp;gt; company.phone, :user =&amp;gt; company.owner)
    Role.find(:all).each { |role| employee.roles &amp;lt;&amp;lt; role }
    company.create_company_setting(:hours_per_day =&amp;gt; 8, :hours_per_week =&amp;gt; 40)
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately, &lt;a href=&quot;http://dev.rubyonrails.org/changeset/7511&quot;&gt;Changeset 7511&lt;/a&gt; has rendered that snippet useless.  The new rule states that the &lt;code&gt;.create&lt;/code&gt; method cannot be called on an association for an unsaved parent.  Previously, the code above would instantiate a new Company object, then silently save it when the owner was assigned.  Now, that line throws an exception instead.&lt;/p&gt;

&lt;p&gt;Here's the Rails 2.0-compatible version.  I'm not sure I like it as much.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&quot;ruby&quot;&gt;def create_with_associations(options)      
  company = self.create(options[:company])
  owner = company.build_owner(options[:user])
  employee = company.employees.build(:title =&amp;gt; &amp;quot;Owner&amp;quot;, :phone =&amp;gt; company.phone, :user =&amp;gt; company.owner)
  Role.find(:all).each { |role| employee.roles &amp;lt;&amp;lt; role }
  setting = company.build_company_setting(:hours_per_day =&amp;gt; 8, :hours_per_week =&amp;gt; 40)

  company
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I think I need to approach the whole tangle from another angle.  Perhaps I need to use the User as the base unit, instead of the Company, and build my associations from there?&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-10-01:24</id>
    <published>2007-10-01T15:13:00Z</published>
    <updated>2007-10-01T15:13:36Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/10/1/new-version-of-rails-arriving-on-track-2-0" rel="alternate" type="text/html"/>
    <title>New Version of Rails, Arriving on Track 2.0</title>
<content type="html">
            &lt;p&gt;OK, title aside, no train puns from me today&#8230; this is exciting news!&lt;/p&gt;

&lt;p&gt;Rails 2.0 has reached &lt;a href=&quot;http://weblog.rubyonrails.com/2007/9/30/rails-2-0-0-preview-release&quot;&gt;Preview Release&lt;/a&gt; status.  Despite the Microsoft-esque syntax, the mood is overwhelmingly upbeat.  Personally, I&#8217;ve been using Edge Rails for all my new development over the past 6 months, but this final drive by the Rails Core team and core contributors has included some great new goodies.&lt;/p&gt;

&lt;p&gt;The changes to the Routing system have received plenty of attention elsewhere, but I wanted to pull out one tidbit which I&#8217;ve only seen posted one other place, &lt;a href=&quot;http://casperfabricius.com/blog/2007/09/18/railsconf2007-dhh/trackback/&quot;&gt;Casper Fabricius&#8217;&lt;/a&gt; excellent recap of DHH&#8217;s keynote address at Railsconf Europe:&lt;/p&gt;

&lt;p&gt;Namespaced Routes are awesome, and a long-overdue addition for any of us who&#8217;ve attempted to create an administration section for our sites.  There&#8217;s a clever bit of &lt;code&gt;form_for&lt;/code&gt; syntax for dealing with namespaced routes.&lt;/p&gt;

&lt;h5&gt;The Old Way&lt;/h5&gt;

&lt;pre&gt;&lt;code&gt;form_for :user, :url =&amp;gt; admin_users_path do |f|
  # new user form 
end

form_for :user, :url =&amp;gt; admin_user_path(@user), 
                :html =&amp;gt; { :method =&amp;gt; :put } do |f|
  # edit user form
end
&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;The New Way&lt;/h5&gt;

&lt;pre&gt;&lt;code&gt;form_for([:admin, @user]) do |f|
  # Works for either!
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Cleaner, more concise, and thoroughly overlooked.  Casper, thanks for bringing this out so we could see it!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-09-10:18</id>
    <published>2007-09-10T17:52:00Z</published>
    <updated>2007-10-02T17:19:39Z</updated>
    <category term="Projects"/>
    <link href="http://www.alloycode.com/2007/9/10/doxtrackr-goes-live" rel="alternate" type="text/html"/>
    <title>Doxtrackr Goes Live</title>
<content type="html">
            &lt;p&gt;After a turbo-charged 48 hour development period, our contest entry has launched!  &lt;a href=&quot;http://www.keithmedlin.com/&quot;&gt;Keith&lt;/a&gt; did an outstanding job on our interface, far exceeding merely doing justice to my application code.  Even more impressive, we managed to implement everything we intended, and simplified the app at the same time.&lt;/p&gt;

&lt;p&gt;Here&#8217;s the short list of features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;*No&lt;/em&gt;* Account Management Required!&lt;/li&gt;
&lt;li&gt;Easy to share &lt;strong&gt;private URLs&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Document &lt;strong&gt;Version &amp;amp; Status Tracking&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Version specific &lt;strong&gt;Comments&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I would argue that our greatest success was removing the account management requirement.  Most of the Rumble contest sites we&#8217;ve viewed so far put the majority of their content behind a login/password screen.  A few of the more generous ones support OpenID, a technology I&#8217;ve recently come to embrace.  &lt;/p&gt;

&lt;p&gt;We take pride in being one of the few applications that offers all the benefit of a session-backed user account without any of the account creation/management overhead.  Simply provide your name and email address when you upload a document and your account is created for you.  If you&#8217;ve uploaded additional documents with the same email address, we&#8217;ll automatically group them together for you.&lt;/p&gt;

&lt;p&gt;&lt;img title=&quot;Team Red Key&quot; src=&quot;http://www.alloycode.com/assets/2007/9/10/redkey-1.png&quot; height=&quot;320&quot; alt=&quot;Team Red Key&quot; width=&quot;480&quot; /&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-09-09:17</id>
    <published>2007-09-09T16:16:00Z</published>
    <updated>2007-09-27T19:35:06Z</updated>
    <category term="Projects"/>
    <link href="http://www.alloycode.com/2007/9/9/36-hours-in" rel="alternate" type="text/html"/>
    <title>36 Hours In...</title>
<content type="html">
            &lt;p&gt;&lt;img title=&quot;LOLKid&quot; src=&quot;http://www.alloycode.com/assets/2007/9/9/lolkid.png&quot; height=&quot;320&quot; alt=&quot;Im in Ur Rails...&quot; width=&quot;480&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Well, I&#8217;m long overdue for a Rumble update, the past 24 hours have been a whirlwind of activity over at &lt;a href=&quot;http://vote.railsrumble.com/teams/19&quot;&gt;team Redkey&lt;/a&gt;.  Our application now supports team collaboration, ActionMailer backed email, and some really cool routing stuff that enables us to use the concept of users without the overhead of making those users log in.&lt;/p&gt;

&lt;p&gt;Also, don&#8217;t forget to check out our &lt;a href=&quot;http://flickr.com/photos/alloyjared/sets/72157601922487605/&quot;&gt;Flickr photos&lt;/a&gt;.  We were fortunate enough to have a guest photographer stop by the morning to take our official team photo, capturing us at our most-rested state in the past day and a half.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-09-08:16</id>
    <published>2007-09-08T21:55:00Z</published>
    <updated>2007-09-08T21:57:02Z</updated>
    <category term="Programming"/>
    <link href="http://www.alloycode.com/2007/9/8/test-coverage-matters" rel="alternate" type="text/html"/>
    <title>Test Coverage Matters</title>
<content type="html">
            &lt;p&gt;&lt;img title=&quot;Test Coverage&quot; src=&quot;http://www.alloycode.com/assets/2007/9/8/coverage.png&quot; height=&quot;320&quot; alt=&quot;100 Percent Test Coverage&quot; width=&quot;480&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Inspired by &lt;a href=&quot;http://pretendpeople.tumblr.com/&quot;&gt;City Cliq's&lt;/a&gt; RSpec screenshot, we wanted to brag on our 100% RCov coverage as well.  We've been using Test::Unit as opposed to RSpec, along with a healthy dose of Mocha to mock out external services.&lt;/p&gt;

&lt;p&gt;For example, our application provides a convenient, tiny url to access user content, which is generated as part of a create action, generated with the &lt;a href=&quot;http://shorturl.rubyforge.org&quot;&gt;ShortURL&lt;/a&gt; gem.  In our functional test, we mock out the &quot;shorten&quot; method of ShortURL, and have it feed us back consistent data:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;def test_create
  WWW::ShortURL.expects(:shorten).returns(&quot;http://tinyurl.com/fake&quot;)
  assert_difference &quot;Document.count&quot;, 1 do
    post :create, :document =&amp;gt; @@document_default_values
    assert_equal &quot;http://tinyurl.com/fake&quot;, assigns(:document).shorturl
  end
end
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since the generated URL could potentially be different each time the test is run, I've removed the dependency on an external library and service to gain repeatability in my tests.  I'll take for granted that the ShortURL gem works and has it's own tests; there's no reason for me to duplicate their efforts.  The above test simply assumes the ShortURL library is performing as expected, and allowing me to test my own code atomically.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.alloycode.com/">
    <author>
      <name>jared</name>
    </author>
    <id>tag:www.alloycode.com,2007-09-08:15</id>
    <published>2007-09-08T18:37:00Z</published>
    <updated>2007-09-27T19:34:34Z</updated>
    <category term="Projects"/>
    <link href="http://www.alloycode.com/2007/9/8/14-hours-of-rumbling" rel="alternate" type="text/html"/>
    <title>14 Hours of Rumbling</title>
<content type="html">
            &lt;p&gt;&lt;img title=&quot;Rails Rumble 2007&quot; src=&quot;/assets/2007/9/8/IMG_7716.jpg&quot; height=&quot;267&quot; alt=&quot;Keith laying out our elements&quot; width=&quot;400&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Well, we&#8217;re just past the 14 hour mark since the Rails Rumble opened, and we&#8217;re making great progress.  &lt;a href=&quot;http://keithmedlin.com/?p=12&quot;&gt;Keith Medlin&lt;/a&gt; and I have resurrected the &#8220;Red Key&#8221; brand to bring our revolutionary vision to life:  &lt;a href=&quot;http://vote.railsrumble.com/teams/19&quot;&gt;Docustackr&lt;/a&gt;, a web-based document revision system.&lt;/p&gt;

&lt;p&gt;The bulk of my time so far has been spent setting up our deployment environment, having done this recently for Alloy Code and Your Garage Online, I was able to speed through most of it.  We&#8217;re using Mongrel, Capistrano and Nginx on Ubuntu 7.04 (breaking from the Debian herd) and have our stack already in place.  We won&#8217;t be struggling to deploy at the last minute!&lt;/p&gt;

&lt;p&gt;Keith has been focusing on our design and interface while I&#8217;ve been putting the models in place to support the site.  We&#8217;ve snapped &lt;a href=&quot;http://www.flickr.com/photos/alloyjared/sets/72157601922487605/&quot;&gt;a few photos&lt;/a&gt; for posterity.&lt;/p&gt;

&lt;p&gt;Keep watching for previews of our design and code process!&lt;/p&gt;
          </content>  </entry>
</feed>
