<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>3hv &#187; Ruby on Rails and Software Development</title>
	<atom:link href="http://www.3hv.co.uk/blog/category/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.3hv.co.uk/blog</link>
	<description>beautiful code for elegant web sites</description>
	<lastBuildDate>Mon, 21 Dec 2009 21:21:14 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using ActiveRecord to connect to Sybase Adaptive Server Anywhere on Windows</title>
		<link>http://www.3hv.co.uk/blog/2009/12/21/using-activerecord-to-connect-to-sybase-adaptive-server-anywhere-on-windows/</link>
		<comments>http://www.3hv.co.uk/blog/2009/12/21/using-activerecord-to-connect-to-sybase-adaptive-server-anywhere-on-windows/#comments</comments>
		<pubDate>Mon, 21 Dec 2009 21:18:33 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[adaptive server anywhere]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sybase]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=619</guid>
		<description><![CDATA[Just don&#8217;t ask why I know this.  Please.  It&#8217;s making me cry.  
Install Ruby using the One Click Installer.
Install the ODBC module (by copying the SO files into the c:\Ruby\1.8\i386-mingw32 folder).
Install the ActiveRecord ODBC adapter (gem install activerecord-odbc-adapter).
Edit C:\Ruby\lib\ruby\gems\1.8\gems\activerecord-odbc-adapter-2.0\ lib\active_record\connection_adapters\odbc_adapter.rb &#8211; look for line 1588.
Change the line from elsif dbmsName =~ /SQLAnywhere/i [...]]]></description>
			<content:encoded><![CDATA[<p>Just don&#8217;t ask why I know this.  Please.  It&#8217;s making me cry.  </p>
<p>Install Ruby using the <a href="http://rubyinstaller.org/">One Click Installer</a>.<br />
Install the <a href="http://ch-werner.de/rubyodbc/">ODBC module</a> (by copying the SO files into the c:\Ruby\1.8\i386-mingw32 folder).<br />
Install the ActiveRecord ODBC adapter (gem install activerecord-odbc-adapter).<br />
Edit C:\Ruby\lib\ruby\gems\1.8\gems\activerecord-odbc-adapter-2.0\ lib\active_record\connection_adapters\odbc_adapter.rb &#8211; look for line 1588.<br />
Change the line from<code> elsif dbmsName =~ /SQLAnywhere/i</code> to <code>elsif dbmsName =~ /SQLAnywhere/i or dbmsName =~ /adaptiveserveranywhere/i</code></p>
<p>Write some test code &#8211; something like: </p>
<p><code><br />
require 'rubygems'<br />
require 'active_record'</p>
<p>ActiveRecord::Base.establish_connection(:adapter => :odbc, :dsn => 'mydsn', :username => 'myusername', :password => 'mypassword')</p>
<p>class Whatever < ActiveRecord::Base</p>
<p>end</p>
<p>Whatever.all<br />
</code><br />
Run this - hopefully you should get no errors.<br />
Then sit down and have a long think about what the hell you are doing.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/12/21/using-activerecord-to-connect-to-sybase-adaptive-server-anywhere-on-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moving attachment_fu files from the local filesystem to Amazon S3</title>
		<link>http://www.3hv.co.uk/blog/2009/11/24/moving-attachment_fu-files-from-the-local-filesystem-to-amazon-s3/</link>
		<comments>http://www.3hv.co.uk/blog/2009/11/24/moving-attachment_fu-files-from-the-local-filesystem-to-amazon-s3/#comments</comments>
		<pubDate>Tue, 24 Nov 2009 20:26:08 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[Amazon S3]]></category>
		<category><![CDATA[attachment_fu]]></category>
		<category><![CDATA[filesystems]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=611</guid>
		<description><![CDATA[attachment_fu may not be the in-thing any more but there are still a lot of sites out there using it.  And every now and then you realise, far too late, that you should have used S3 instead of the local filesystem.  
Switching is easy &#8211; just change the :storage parameter to :s3.  [...]]]></description>
			<content:encoded><![CDATA[<p>attachment_fu may not be the in-thing any more but there are still a lot of sites out there using it.  And every now and then you realise, far too late, that you should have used S3 instead of the local filesystem.  </p>
<p>Switching is easy &#8211; just change the :storage parameter to :s3.  But before you can do that, how do you get the existing files onto S3 in the first place?  </p>
<p>Well, here&#8217;s your answer.  </p>
<p><strong>Before</strong> you change the storage parameter, create you S3 account and a bucket to store your files.  </p>
<p>Then add a new rake task to your application, looking something like this: </p>
<pre><code>
  desc "Upload files to S3"
  task :upload_files_to_s3 => :environment do

    AWS::S3::Base.establish_connection!(
      :access_key_id => 'MYACCESSKEY',
      :secret_access_key => 'MYSECRETKEY')

    Model.find(:all).each do | user |
      filename = "/home/user/app/current/public#{model.public_filename}"
      puts "Migrating model #{model.id} - #{filename}"
      if File.exists?(filename)
        AWS::S3::S3Object.store("/models/#{model.id}/#{model.filename}",
          open(filename),
          'my_bucket',
          :access => :public_read)
        puts "...migrated"
      else
        puts "...not found"
      end
    end
  end
</code></pre>
<p>In other words; </p>
<ul>
<li>connect to S3</li>
<li>for each &#8220;model&#8221; instance, find the attachment on the local filesystem</li>
<li>if found, then push it to S3, using /models/id/filename as the key (where models is your table name)</li>
</ul>
<p>As soon as you&#8217;ve done that, switch the :storage to :s3 and redeploy your app (not forgetting your config/amazon_s3.yml file).  And, with a bit of luck, you should see your files being served from Amazon&#8217;s servers, instead of your own.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/11/24/moving-attachment_fu-files-from-the-local-filesystem-to-amazon-s3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Favourite code</title>
		<link>http://www.3hv.co.uk/blog/2009/11/12/favourite-code/</link>
		<comments>http://www.3hv.co.uk/blog/2009/11/12/favourite-code/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 22:31:53 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[Beautiful Code]]></category>
		<category><![CDATA[General]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[bigwig]]></category>
		<category><![CDATA[brightbox]]></category>
		<category><![CDATA[caius durling]]></category>
		<category><![CDATA[david smalley]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[object factory]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=607</guid>
		<description><![CDATA[I think Bigwig has become my favourite bit of code that I&#8217;ve ever worked on.  
Before Bigwig, it was Object Factory, before that it was a Delphi class that I used to create tree-structured data (imaginatively called TNode).  
Bigwig&#8217;s doesn&#8217;t have a test suite and it&#8217;s not even my code &#8211; it was [...]]]></description>
			<content:encoded><![CDATA[<p>I think <a href="http://github.com/brightbox/bigwig">Bigwig</a> has become my favourite bit of code that I&#8217;ve ever worked on.  </p>
<p>Before Bigwig, it was <a href="http://github.com/brightbox/object-factory">Object Factory</a>, before that it was a Delphi class that I used to create tree-structured data (imaginatively called TNode).  </p>
<p>Bigwig&#8217;s doesn&#8217;t have a test suite and it&#8217;s not even my code &#8211; it was started by <a href="http://davidsmalley.com/">David Smalley</a> and has contributions from <a href="http://caius.name/">Caius Durling</a> and the rest of the Brightbox team.  </p>
<p>But there&#8217;s just something about it &#8211; it&#8217;s a daemon (start it running and forget about it); it&#8217;s been running in production for months without a single glitch; and probably most importantly, the code is so simple that there&#8217;s almost nothing to it. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/11/12/favourite-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Posting gems to Rubyforge</title>
		<link>http://www.3hv.co.uk/blog/2009/10/06/posting-gems-to-rubyforge/</link>
		<comments>http://www.3hv.co.uk/blog/2009/10/06/posting-gems-to-rubyforge/#comments</comments>
		<pubDate>Tue, 06 Oct 2009 18:20:04 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=588</guid>
		<description><![CDATA[Github aren&#8217;t building new gems at the moment as they finalise their move to Rackspace.  So what do you do if you&#8217;ve got a gem that you would like to make available?  
Gemcutter&#8217;s the new kid on the block &#8211; it works as a set of plugins to the gem command that mean [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://github.com">Github</a> aren&#8217;t building new gems at the moment as they finalise their move to Rackspace.  So what do you do if you&#8217;ve got a gem that you would like to make available?  </p>
<p><a href="http://gemcutter.org">Gemcutter&#8217;s</a> the new kid on the block &#8211; it works as a set of plugins to the gem command that mean you can simply go `gem push my.gem` and it becomes available to the world.  Nice as this is, gemcutter&#8217;s still pretty young and is currently hosted off <a href="http://www.mail-archive.com/rubygems-developers@rubyforge.org/msg03123.html">one guy&#8217;s S3 account</a>.  </p>
<p>So we went back to good old-fashioned <a href="http://rubyforge.org">Rubyforge</a>.  Except, believe it or not, I&#8217;d never published to Rubyforge before.  And it wasn&#8217;t as straightforward as it could have been.  </p>
<p>I was using the <a href="http://github.com/fauna/echoe">echoe</a> library to build my gem &#8211; which gave me a simple `rake manifest`, `rake release` workflow.  All good.  When you `rake release` it asks if you want to publish to rubyforge; you say &#8220;yes&#8221; and go to bed happy.  </p>
<p>Or not in my case.  </p>
<p>Firstly, you need to actually configure rubyforge.  Install the rubyforge gem, then use `rubyforge setup` to put in your username and password.  Then use `rubyforge config` to make them stick.  </p>
<p>That done, I `rake release`d.  And got a &#8220;no group_id configured for mygem&#8221; error.  Eh?  Googling seemed no help whatsoever &#8211; it was mentioned in a few places but people seemed to have resolved it without actually posting their solutions (or I was being blind).  </p>
<p>What you need to do is tell Rubyforge where to put your gem.  In our case we already had a project on Rubyforge that the gem could be attached to &#8211; so `rubyforge create_package project_name gem_name` did the trick.  Otherwise you need to get a project set up to house your gem.  </p>
<p>But it still didn&#8217;t work.  This time complaining about a processor id.  I had no idea what I was looking for this time, until I discovered this <a href="http://pastie.org/180892">pastie</a> by Dr Nic.  The autogenerated config file (normally in ~/.rubyforge/auto-config.yml) is missing some vital information &#8211; namely codes for different processor architectures.  I pasted the list into your config file and then tried the `rake release` again.  And this time it worked!</p>
<pre><code>
processor_ids:
  IA64: 6000
  AMD-64: 1500
  Any: 8000
  Sparc: 4000
  PPC: 2000
  Other: 9999
  Alpha: 7000
  i386: 1000
  UltraSparc: 5000
  MIPS: 3000
</code></pre>
<p>So for the sake of posterity &#8211; and anyone else who gets &#8220;no group_id configured for mygem&#8221; or &#8220;no processor_id configured for mygem&#8221; messages, I thought I should let you know how I got there.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/10/06/posting-gems-to-rubyforge/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>It happens to the best of us</title>
		<link>http://www.3hv.co.uk/blog/2009/10/05/it-happens-to-the-best-of-us/</link>
		<comments>http://www.3hv.co.uk/blog/2009/10/05/it-happens-to-the-best-of-us/#comments</comments>
		<pubDate>Mon, 05 Oct 2009 16:21:53 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[Writing Reliable, Bug-Free Code]]></category>
		<category><![CDATA[Bug-Free Code]]></category>
		<category><![CDATA[bugs]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Writing Reliable]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=581</guid>
		<description><![CDATA[We just had some customers report a bug. Not good. We didn&#8217;t get an exception email. All the tests passed. We couldn&#8217;t see anything untoward in the log files.  But it was there. We could reproduce it, both in staging and in production. Not good at all. 
But the weirdest thing was we couldn&#8217;t [...]]]></description>
			<content:encoded><![CDATA[<p>We just had some customers report a bug. Not good. We didn&#8217;t get an exception email. All the tests passed. We couldn&#8217;t see anything untoward in the log files.  But it was there. We could reproduce it, both in staging and in production. Not good at all. </p>
<p>But the weirdest thing was we couldn&#8217;t figure out the cause. Well I could see why the code was failing (after adding some extra log messages). But &#8216;git blame&#8217; said those lines of code were unchanged in twelve months.  Why hadn&#8217;t people complained before?  Why hadn&#8217;t we <em>noticed</em> it?</p>
<p>After much hunting through log files we found the point when the feature last worked. It coincided with a deployment. That deployment was our Rails 2.3.4 forms vulnerability fix. And the bug was in a form &#8211; a missing form parameter that earlier versions of Rails ignored, the newer Rails was choking on.  </p>
<p>But why didn&#8217;t the tests catch it?  </p>
<p>After more hunting I saw that the Cucumber test that exercised the form didn&#8217;t have a &#8220;When I press the Update button&#8221; step.  And the subsequent tests were passing, even though the update button hadn&#8217;t been pressed.  </p>
<p>So I added the step in and made the feature pass.  Then deployed it as an emergency fix.  </p>
<p>However, what are the lessons to learn here (as there are always some)? </p>
<ul>
<li>Firstly, testing cannot catch everything.  </li>
<li>Secondly, the cracks in your tests are where the bugs are.  </li>
<li>Thirdly, we probably need some sort of peer review for tests.  I feel that this is more important than for code, because once the tests are right you can refactor the code without worry.  </li>
<li>Fourthly, you really need to <strong>log everything</strong>.  Absolutely everything.  Don&#8217;t worry about your huge log files &#8211; that&#8217;s what `logrotate` is for.  Get it written down so that one time when you have an obscure bug, you&#8217;ll be able to find it easily.  </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/10/05/it-happens-to-the-best-of-us/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Constructors in Ruby are not guaranteed to be called</title>
		<link>http://www.3hv.co.uk/blog/2009/06/03/constructors-in-ruby-are-not-guaranteed-to-be-called/</link>
		<comments>http://www.3hv.co.uk/blog/2009/06/03/constructors-in-ruby-are-not-guaranteed-to-be-called/#comments</comments>
		<pubDate>Wed, 03 Jun 2009 21:28:58 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[constructors]]></category>
		<category><![CDATA[language]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=557</guid>
		<description><![CDATA[Today, Caius made a discovery that shocked me.  
He had a class, descending from ActiveRecord::Base, with a custom constructor (initialize method).  To debug it, he had the constructor raise an exception.  In the console, Thingy.new(params) raised the exception as expected.  But wotsit.thingies.find_by_field(value) did not.  Even though it was instantiating an [...]]]></description>
			<content:encoded><![CDATA[<p>Today, <a href="http://caius.name/">Caius</a> made a discovery that shocked me.  </p>
<p>He had a class, descending from ActiveRecord::Base, with a custom constructor (initialize method).  To debug it, he had the constructor raise an exception.  In the console, <code>Thingy.new(params)</code> raised the exception as expected.  But <code>wotsit.thingies.find_by_field(value)</code> did not.  Even though it was instantiating an instance of Thingy and returning it.  </p>
<p>&#8220;It must not be calling the constructor&#8221; he said.<br />
&#8220;Rubbish&#8221; said I, &#8220;it&#8217;s a constructor.  Constructors are always called.  That&#8217;s the point of them&#8221;.  </p>
<p>But as he dug deeper it certainly looked like the constructor wasn&#8217;t being called.  </p>
<p>And then he found an article explaining that you should <a href="http://blog.dalethatcher.com/2008/03/rails-dont-override-initialize-on.html">never rely</a> on things being set up on in an Active Record constructor.  Mainly because Active Record uses <code>allocate</code> to instantiate associated objects.  And what is this mysterious allocate?  Why <a href="http://whytheluckystiff.net/articles/rubyOneEightOh.html">explains it all</a>.  </p>
<p>To be honest, I&#8217;ve got mixed feelings about this.  I can see the use of &#8220;allocate&#8221; &#8211; why&#8217;s example of marshalling an object makes sense (I&#8217;m slightly less sure about the way that Active Record uses it to load associations).  But, to my mind, the definition of a constructor is &#8220;the code that is always called when an object is created&#8221;.  So maybe I should just stop thinking of <code>initialize</code> as a constructor and more as an initialiser.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/06/03/constructors-in-ruby-are-not-guaranteed-to-be-called/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Note to self: comparing two branches in git and squashing several commits into one</title>
		<link>http://www.3hv.co.uk/blog/2009/06/02/note-to-self-comparing-two-branches-in-git-and-squashing-several-commits-into-one/</link>
		<comments>http://www.3hv.co.uk/blog/2009/06/02/note-to-self-comparing-two-branches-in-git-and-squashing-several-commits-into-one/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 19:49:45 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Managing Successful Projects]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[branches]]></category>
		<category><![CDATA[commits]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[source control]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=548</guid>
		<description><![CDATA[I always forget how to do this so I&#8217;m writing it down (especially as it&#8217;s really easy and git, as usual, makes me feel stupid as Linus is so much smarter than me).  
Suppose you&#8217;ve been working in branch X and you&#8217;re about to merge those changes into branch Y &#8230;

work in branch X [...]]]></description>
			<content:encoded><![CDATA[<p>I always forget how to do this so I&#8217;m writing it down (especially as it&#8217;s really easy and git, as usual, makes me feel stupid as Linus is so much smarter than me).  </p>
<p>Suppose you&#8217;ve been working in branch X and you&#8217;re about to merge those changes into branch Y &#8230;</p>
<ul>
<li>work in branch X and make your commits as needed</li>
<li>switch to branch Y <code>git checkout Y</code></li>
<li>compare the differences between X and Y <code>git log Y..X</code> &#8211; the order here is important; it is merge-target..merge-source</li>
<li>merge the changes from X (merge-source) into Y (merge-target) <code>git merge X</code></li>
</ul>
<p>Even better, before doing the merge, while you are still in branch X, you can squash multiple commits into a single one.  This way, branch Y, when you examine the log, has a single entry &#8220;implemented feature X&#8221;, instead of thirty-five entries all related to feature X in some way.  </p>
<ul>
<li>examine the log <code>git log</code> or even better <code>git log --pretty=oneline</code></li>
<li>choose the commit that immediately precedes the one that starts your piece of work (probably the last one before you branched to start work on feature X)</li>
<li>start an interactive rebase session &#8211; this is git-fancy-talk for picking some commits and typing a message &#8211; <code>git rebase -i THE-COMMIT-ID-OF-THE-COMMIT-YOU-SELECTED-ABOVE</code></li>
<li>Your favourite editor (or nano) will open listing the commits for feature X &#8211; edit the word &#8220;pick&#8221; to &#8220;squash&#8221; for all except the top entry, save and exit</li>
<li>Your favourite editor will open again &#8211; again showing your commit messages &#8211; add a line <em>at the top</em> stating something like &#8220;implementation of feature X&#8221; and leave the list of individual commits on separate lines below it (adding in a Fixes #123 or whatever your issue tracker demands as the last line), save and exit</li>
<li>Now if you do a <code>git log</code> you will see a single commit with a nice &#8220;implementation of feature X&#8221; log message</li>
<li>And you&#8217;re all set to merge to your master branch without cluttering its history with a long string of commit messages</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/06/02/note-to-self-comparing-two-branches-in-git-and-squashing-several-commits-into-one/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>My cron jobs and rake tasks won&#8217;t write to the Rails log file</title>
		<link>http://www.3hv.co.uk/blog/2009/06/01/my-cron-jobs-and-rake-tasks-wont-write-to-the-rails-log-file/</link>
		<comments>http://www.3hv.co.uk/blog/2009/06/01/my-cron-jobs-and-rake-tasks-wont-write-to-the-rails-log-file/#comments</comments>
		<pubDate>Mon, 01 Jun 2009 21:34:09 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[clusters]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[logger]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=542</guid>
		<description><![CDATA[A project I&#8217;ve been working on was recently moved up to Rails 2.2 (Rails 2.3 migration coming soon, but we wanted to take things one step at a time).  
All the tests passed.  Poking it on the staging server worked well.  On to production and all was good.  
Time passed.  [...]]]></description>
			<content:encoded><![CDATA[<p>A project I&#8217;ve been working on was recently moved up to Rails 2.2 (Rails 2.3 migration coming soon, but we wanted to take things one step at a time).  </p>
<p>All the tests passed.  Poking it on the staging server worked well.  On to production and all was good.  </p>
<p>Time passed.  </p>
<p>Then, the app needed to be moved to a new server.  Actually to a cluster.  Slightly more nerve-wracking, but some playing around with the <a href="http://github.com/bjeanes/ghost/tree/master">ghost</a> gem and DNS settings and the deployment completed.  </p>
<p>More time passed.  </p>
<p>And then disaster struck.  Well, not disaster, but it wasn&#8217;t good.  Not at all.   </p>
<p>The app had a rake task that was cronned to run every night.  And it failed silently.  We found out the day after and I scanned the production log file looking for evidence of what went wrong.  Nowt.  It didn&#8217;t even look like the rake task had run &#8211; but it had, as I had the data in front of me.  </p>
<p>And the day after, it failed again.  Another scan of the production log revealed nothing.  Things were getting serious.  </p>
<p>I suspected the cluster deployment.  Maybe cron didn&#8217;t have permission to write to the log file, even though Passenger did.  But everything looked good on that front.  Maybe there was something else weird about the cluster setup &#8211; all the cron jobs were set to run on one of the app-servers; maybe moving it would make a difference?  </p>
<p>To test this, I opened the Rails console and started manually recreating what the rake task was doing, on a different app-server.  Which is when I noticed that script/console wasn&#8217;t writing to the production log either.  What?  </p>
<p>After a couple of hours of head scratching, I finally found out that the cluster deployment was not at fault.  In fact, it seems to be the move to Rails 2.2 that had happened many weeks before &#8211; in particular it appears that the logger object no longer auto-flushes itself after writing.  </p>
<p>We added a quick <code>Rails.logger.auto_flushing = 1</code> to an initialiser and both script/console and the rake tasks wrote to the log as expected.  Phew!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/06/01/my-cron-jobs-and-rake-tasks-wont-write-to-the-rails-log-file/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Cucumber to estimate a project</title>
		<link>http://www.3hv.co.uk/blog/2009/05/15/using-cucumber-to-estimate-a-project/</link>
		<comments>http://www.3hv.co.uk/blog/2009/05/15/using-cucumber-to-estimate-a-project/#comments</comments>
		<pubDate>Fri, 15 May 2009 16:39:45 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[Designing Great Software]]></category>
		<category><![CDATA[Managing Successful Projects]]></category>
		<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[Writing Reliable, Bug-Free Code]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[design]]></category>
		<category><![CDATA[estimates]]></category>
		<category><![CDATA[project planning]]></category>
		<category><![CDATA[requirements gathering]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=521</guid>
		<description><![CDATA[Writing estimates up-front is a really tricky part of client work.  
From the customer&#8217;s point of view it&#8217;s pretty essential.  You need to know how much you are spending before the work begins so you don&#8217;t get stung.    
From the developer&#8217;s point of view it&#8217;s pretty difficult to do because [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.3hv.co.uk/blog/wp-content/uploads/2009/05/281211_6743jpg-300x225.jpg" alt="Invoice" title="Invoice" width="300" height="225" class="alignright size-medium wp-image-524" style="margin: 4px" />Writing estimates up-front is a really tricky part of client work.  </p>
<p>From the customer&#8217;s point of view it&#8217;s pretty essential.  You need to know how much you are spending before the work begins so you don&#8217;t get stung.    </p>
<p>From the developer&#8217;s point of view it&#8217;s pretty difficult to do because you don&#8217;t know how long things will take until you know what you&#8217;re building.  And you don&#8217;t know the details of what you are building until they become apparent, which is normally while you are doing the work.  </p>
<p>For this particular client I wanted to get this piece of work out of the way as quickly as possible and the requirements were deceptively complicated.  As trying to deal with intangibles is a recipe for disaster, and time was short, I was pretty sure that whatever estimate I came up with would be totally inaccurate.  </p>
<p>So to deal with the intangibles I thought I may as well get stuck in with the actual work.  And what&#8217;s the first thing that I do?  Write a <a href="http://cukes.info">cucumber</a> story.  </p>
<p>I went through the requirements documents (which after weeks of to and fro were actually quite detailed and refined) and broke it down into four features, each with a number of scenarios.  Each scenario was then broken down into individual steps &#8211; however, I did not write any step definition (ruby) files.  This is cucumber as customer documentation, not as integration testing.  </p>
<p>We agreed that the features met the requirements (the client was very impressed with the level of detail and the clarity that cucumber offered) and I simply went through each feature, scenario and step and came up with a price for the step individually.  It&#8217;s still guesswork, but it&#8217;s guesswork on a small scale, so you&#8217;re less likely to be way off.  Total the lot and there&#8217;s your estimate.  </p>
<p>And even better, once the client has agreed the price and you&#8217;ve started development, you&#8217;ve got a development plan, a measure of progress and proof that it all works &#8211; all just a simple <tt>rake features</tt> away.  </p>
<p><small>Image by <a href="http://www.sxc.hu/profile/lemon_drop">lemon drop</a></small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/05/15/using-cucumber-to-estimate-a-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Switching off transactions for a single spec when using RSpec</title>
		<link>http://www.3hv.co.uk/blog/2009/05/08/switching-off-transactions-for-a-single-spec-when-using-rspec/</link>
		<comments>http://www.3hv.co.uk/blog/2009/05/08/switching-off-transactions-for-a-single-spec-when-using-rspec/#comments</comments>
		<pubDate>Fri, 08 May 2009 10:44:28 +0000</pubDate>
		<dc:creator>Rahoul Baruah</dc:creator>
				<category><![CDATA[Ruby on Rails and Software Development]]></category>
		<category><![CDATA[Writing Reliable, Bug-Free Code]]></category>
		<category><![CDATA[Bug-Free Code]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[transactions]]></category>
		<category><![CDATA[Writing Reliable]]></category>

		<guid isPermaLink="false">http://www.3hv.co.uk/blog/?p=503</guid>
		<description><![CDATA[I have just written a load of test code that needed to verify that a particular set of classes behaved correctly when a transaction was rolled back.  
However, the rest of my suite relied on transactional fixtures (which is Rails&#8217; badly named way of saying that a transaction is started before each test and [...]]]></description>
			<content:encoded><![CDATA[<p>I have just written a load of test code that needed to verify that a particular set of classes behaved correctly when a transaction was rolled back.  </p>
<p>However, the rest of my suite relied on transactional fixtures (which is Rails&#8217; badly named way of saying that a transaction is started before each test and rolled back at the end, leaving your test database in a pristine state before the next case is run). </p>
<p>In particular, my spec_helper.rb had the following:</p>
<pre>
Spec::Runner.configure do |config|
  config.use_transactional_fixtures = true
  # stuff
end
</pre>
<p>The code being tested looked something like this: </p>
<pre>
begin
  Model.transaction do
    do_something # may fail with an exception
    do_something_else # may fail with an exception
  end
rescue Exception => ex
  do_some_recovery_stuff
end
</pre>
<p>I had a spec for the successful path (checking that the outcomes of <tt>do_something</tt> and <tt>do_something_else</tt> were what I expected.  </p>
<p>However when I tried the same for the failure paths, the outcomes matched the successful path.  The time-tested debugging method of sticking some <tt>puts</tt> statements in various methods showed that <tt>do_some_recovery_stuff</tt> was being called as expected.  But the outcomes were still wrong.  </p>
<p>And the reason?  Transactions.  This was a Rails 2.2 project, running on Mysql (innodb).  As RSpec/Test::Unit starts a transaction before the specification clause runs (and then rolls it back on completion) when <tt>Model.transaction</tt> statement is reached, the spec is actually starting a second transaction, nested within RSpec/Test:Unit&#8217;s.  Which means when the inner transaction is rolled back, the database doesn&#8217;t actually do anything &#8211; there&#8217;s still an outer transaction that may or may not be rolled back.  (I think Rails 2.3 corrects this behaviour and if you roll back an inner transaction then the outer transaction reflects the correct state, but I&#8217;m not 100% on that).  </p>
<p>So I had a choice &#8211; move the (production) app to Rails 2.3 to fix this one bug (which is very urgent) or figure out how to switch the outer transaction off for these particular steps.  Google wasn&#8217;t very helpful &#8211; lots of stuff on how RSpec extends Test::Unit, lots of stuff on how Rails extends Test::Unit to add the fixtures (and transaction) support.  But no concrete example on how to actually switch it off. </p>
<p>After much playing around (overriding methods like <tt>use_transaction?(method_name)</tt> and <tt>runs_in_transaction?</tt>) I eventually stumbled across the answer.  And it&#8217;s pretty simple.  </p>
<p>Set your default to be <tt>config.use_transactional_fixtures = true</tt> in spec_helper.rb.  Then, for the specs that are not transactional, simply create a <tt>describe</tt> block and simply add the following: </p>
<pre>
describe MyClass, "when doing its stuff" do
  self.use_transactional_fixtures = false
  it "should do this"
  it "should do that"
  it "should do the other"
end
</pre>
<p>The only thing to be aware of is you may well need an <tt>after :each</tt> block to clean up after yourself.  </p>
]]></content:encoded>
			<wfw:commentRss>http://www.3hv.co.uk/blog/2009/05/08/switching-off-transactions-for-a-single-spec-when-using-rspec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
