<?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>Boost Blog &#187; Ruby on Rails</title>
	<atom:link href="http://www.boost.co.nz/blog/category/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.boost.co.nz/blog</link>
	<description>All the stuff we love - Web design &#124; Usability &#124; Ruby on Rails &#124; Agile and Scrum &#124; eLearing</description>
	<lastBuildDate>Wed, 18 Aug 2010 22:44:31 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>Custom application and CMS integration</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/custom-application-and-cms-integration/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/custom-application-and-cms-integration/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 02:25:48 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[radiant]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=773</guid>
		<description><![CDATA[When we release a SaaS web application, such as IntuitionHQ, it&#8217;s inevitable that there will be two parts that make it up. The main part is the application itself. The second part is the marketing site that goes with it. The marketing site includes the content, and usually a way to sign up. It normally [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fcustom-application-and-cms-integration%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fcustom-application-and-cms-integration%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=radiant,rails,ruby" height="61" width="50" /><br />
			</a>
		</div>
<p>When we release a SaaS web application, such as <a href="http://www.intuitionhq.com">IntuitionHQ</a>, it&#8217;s inevitable that there will be two parts that make it up. The main part is the application itself. The second part is the marketing site that goes with it. The marketing site includes the content, and usually a way to sign up. It normally requires some integration with the application.</p>
<p>We choose <a href="http://radiantcms.org/">Radiant</a> for our CMS when working on internal projects. The reason we like it is for it&#8217;s simplicity and power. In this post I&#8217;ll go through the different ways we&#8217;ve experimented with to integrate our SaaS applications with Radiant based websites.</p>
<p><span id="more-773"></span></p>
<h3>1. Completely separate</h3>
<p>The first scenario is the simplest. We just keep the website and application completely separated. When the user clicks to sign up they are taken to a form running in the application.</p>
<p>Example: <a href="http://www.sonarhq.com">www.sonarhq.com</a></p>
<p><strong>Pros</strong></p>
<ul>
<li>Very easy.</li>
</ul>
<p><strong>Cons</strong></p>
<ul>
<li>We have to make a sign up form somewhere. In this scenario it&#8217;s easier to do that on the application side, but that means getting the design of that page to match with the website. Doing it this way means that you can&#8217;t really have the sign up form on the homepage.</li>
<li>You can&#8217;t edit the sign up page content through the CMS.</li>
<li>Having two separate administrative interfaces, one for editing the CMS and one for the SaaS application. This is okay, but it involves more work setting up. For an application where users sign up for an account it also means having that extra admin layer, which is a bit confusing.</li>
</ul>
<h3>2. Completely integrated</h3>
<p>Radiant&#8217;s extension system is very powerful. You can actually write a whole Rails application as an extension. This makes it really easy to integrate both the public side and the administrative side of the site.</p>
<p>For some applications this method works very well and reduces complexity.</p>
<p><a href="http://www.saturnflyer.com/blog/jim/2010/04/14/radiant-projects-and-rails-applications/">This recent blog post</a> by Jim Gay, the lead developer of Radiant addresses some of the issues with integrated applications.</p>
<p>Example: <a href="http://www.smartmove.co.nz">www.smartmove.co.nz</a></p>
<p><strong>Pros</strong></p>
<ul>
<li>It&#8217;s reasonably easy to set up.</li>
<li>Everything is completely integrated. You can have the sign up form anywhere you want. You can create Radiant tags to integrate with editable content. You can add tabs to Radiant&#8217;s admin interface for your own admin pages.</li>
</ul>
<p><strong>Cons</strong></p>
<ul>
<li>You have to battle with a slightly different setup. It&#8217;s not too big a of a deal, but it does have an effect. For example, I&#8217;ve found it harder to get the specs running.</li>
<li>You&#8217;re effectively tied to the version of Rails used by Radiant. You can&#8217;t upgrade Rails without updating Radiant, and you can&#8217;t update Radiant without updating Rails.</li>
<li>Radiant has built in user and role models, which you have to work around to avoid conflicting with the way you want to set up models for your own application.</li>
<li>You have to careful that you don&#8217;t end up customising Radiant. If that happens you might find yourself in the position of never being able to upgrade it, and being stuck with that version forever.</li>
</ul>
<h3>3. Admin API and Radiant extension</h3>
<p>With this method your application exposes a locked down administrative API. A simple Radiant extension uses the API to allow sign ups and perform administration.</p>
<p>While this is a more complex solution, it really provides the best of completely separate and completely integrated. You can maintain different Rails and Radiant upgrade paths, but you can still have all of the administration happen in the Radiant backend. You can even build it out to do other interesting things. For example, having a Radiant website that administrates several applications.</p>
<p>Example: <a href="http://www.intuitionhq.com">www.intuitionhq.com</a></p>
<p><strong>Pros</strong></p>
<ul>
<li>Separate codebases.</li>
<li>Single place to administrate both applications.</li>
<li>Sign up form can be placed anywhere on the marketing site.</li>
</ul>
<p><strong>Cons</strong></p>
<ul>
<li>Complicated to setup.</li>
<li>You must consider the security of your administrative API.</li>
</ul>
<h3>Conclusion</h3>
<p>I would avoid having a completely separate website and SaaS application again &#8211; it seemed like a good idea, but ended up not working that well.</p>
<p>Integrating with Radiant is a really nice solution. I would consider it for any application that fits the following:</p>
<ul>
<li>Can and will be developed very rapidly</li>
<li>User/Role system fits in with the one provided by Radiant</li>
</ul>
<p>For all other cases I would expose an admin API and write a simple Radiant extension around it. This seems to be the most future proof, while not taking away any flexibilty. I&#8217;d be interested to hear how other people integrate a marketing site with their SaaS applications.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/custom-application-and-cms-integration/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Hosting in the cloud</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/hosting-in-the-cloud/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/hosting-in-the-cloud/#comments</comments>
		<pubDate>Wed, 28 Oct 2009 21:51:47 +0000</pubDate>
		<dc:creator>Nathan</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[Hosting]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=494</guid>
		<description><![CDATA[It&#8217;s been a busy time here at Boost, and we have just released our new web usability testing application IntuitionHQ. I&#8217;ll be writing a post about IntuitionHQ soon, but today I&#8217;d like to talk about hosting. When we launched SonarHQ in April we decided to host on Slicehost. There were two main reasons we went [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fhosting-in-the-cloud%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fhosting-in-the-cloud%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=Deployment,Development,Hosting,rails,ruby" height="61" width="50" /><br />
			</a>
		</div>
<p>It&#8217;s been a busy time here at Boost, and we have just released our new web usability testing application <a title="Web usability made easy" href="http://www.intuitionhq.com" target="_blank">IntuitionHQ</a>. I&#8217;ll be writing a post about IntuitionHQ soon, but today I&#8217;d like to talk about hosting.</p>
<p>When we launched <a href="http://www.sonarhq.com" target="_blank">SonarHQ</a> in April we decided to host on <a href="http://www.slicehost.com/" target="_blank">Slicehost</a>. There were two main reasons we went with a virtualised hosting solution. The first was that we were not sure whether we would be scaling vertically (bigger, faster servers) or horizontally (splitting different functions onto different servers), and the second was the we wanted to be able to scale up and down in a fine-grained way.</p>
<p>Our initial approach with SonarHQ was to have 2 applications servers, 2 database servers and a utility server (for background tasks including mail). This approach gave us some redundancy and the ability to scale in either horizontally or vertically as needed. This has worked well, but we didn&#8217;t feel that the performance/price ratio is particularly good.</p>
<p>During our initial testing, we had IntuitionHQ setup at Slicehost in the same way. As we were preparing to launch, <a href="http://www.engineyard.com/" target="_blank">Engine Yard</a> released <a href="http://www.engineyard.com/products/cloud" target="_blank">Engine Yard Cloud</a>. Built on top of the Amazon cloud infrastructure, Engine Yard Cloud provides a managed instance and configuration engine specifically optomised for hosting Ruby on Rails applications.</p>
<p>It was easy and painless to get <a title="Web usability made easy" href="http://www.intuitionhq.com" target="_blank">IntuitionHQ</a> up and running on Engine Yard Cloud &#8211; taking under an hour from start to finish. I don&#8217;t think it could have been any easier – everything just seems to work! We fired up a small instance and put through a quick series of load tests. It was evident even with casual clicking through the application that we were getting better response times. Working through the likely costs for hosting on Engine Yard Cloud, we found that we could use a 32bit, 5 ECU, 1.7GB RAM  instance for around the same cost as our previous setup and get a useful boost in both performance and manageability.</p>
<p>One of the most significant benefits is the ability to scale vertically all the way to a 64bit, 20 ECU, 68GB RAM instance with a simple restart. Scaling horizontally is just as easy, and Engine Yard Cloud really takes the pain out of this.</p>
<p>Another important benefit has been the streamlining of our deployment processes. Engine Yard takes care of everything needed for automated deployments, and any custom deployment tasks are easily handled with <a href="http://wiki.opscode.com/display/chef/Home" target="_blank">Chef</a> recipes. Deploying multiple application instances is easy and works seamlessly, with Engine Yard implementing a proxying system with failover across all instances without the need for a separate proxy instance (and single point of failure) &#8211; a significant cost saving. Running a seperate instance (or set of instances) for the databases is as easy as ticking a checkbox.</p>
<p>The image used for the instance is kept up to date with the latest security and reliability patches and is used each time our application is deployed. This gives you a semi-managed hosting system without any of the associated costs.</p>
<p>The margin over standard Amazon EC2 is reasonably high for the small instances but reduces to a 10% premium on the biggest instances. This is very reasonable and for us makes a great deal of sense.</p>
<p>The one thing that would make this much more affordable is the ability to use <a href="http://aws.amazon.com/ec2/reserved-instances/" target="_blank">Amazon reserved instances</a>. These give you a discounted hourly rate for the instance once a one off payment is made. If you know what you need and can commit to a year, this can effectively half the hosting costs.</p>
<p>We launched <a title="Web usability made easy" href="http://www.intuitionhq.com" target="_blank">IntuitionHQ</a> a week ago and have been extremely happy with the performance and utility of Engine Yard Cloud. We are looking forward to growing IntuitionHQ and are confident that Engine Yard Cloud can grow with us.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/hosting-in-the-cloud/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Squirrel and the custom nut matcher</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/squirrel-and-the-custom-nut-matcher/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/squirrel-and-the-custom-nut-matcher/#comments</comments>
		<pubDate>Fri, 11 Sep 2009 04:01:05 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=451</guid>
		<description><![CDATA[I recently found squirrel, and I wanted to use it for a project we&#8217;re working on to simplify some complex finder statements. Squirrel allows turning something like this: Task.find&#40;:all, :conditions =&#38;gt; &#91; 'active = ? and (updated_at &#38;gt; cache_version or cache_version IS NULL)', true &#93; &#41; into: Task.find&#40;:all&#41; do active == true any do updated_at [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fsquirrel-and-the-custom-nut-matcher%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fsquirrel-and-the-custom-nut-matcher%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=rails,rspec,ruby,tdd" height="61" width="50" /><br />
			</a>
		</div>
<p>I recently found <a href="http://www.thoughtbot.com/projects/squirrel">squirrel</a>, and I wanted to use it for a project we&#8217;re working on to simplify some complex finder statements. Squirrel allows turning something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Task.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>,
  <span style="color:#ff3333; font-weight:bold;">:conditions</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span>
    <span style="color:#996600;">'active = ? and (updated_at &amp;gt; cache_version or cache_version IS NULL)'</span>, <span style="color:#0000FF; font-weight:bold;">true</span>
  <span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>into:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Task.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  active == <span style="color:#0000FF; font-weight:bold;">true</span>
  any <span style="color:#9966CC; font-weight:bold;">do</span>
    updated_at <span style="color:#006600; font-weight:bold;">&amp;</span>gt; cache_version
    cache_version.<span style="color:#0000FF; font-weight:bold;">nil</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>The problem is testing</h3>
<p>Then I ran into a serious problem &#8211; how to test this piece of code using rspec? Here was my first attempt:<span id="more-451"></span></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">'should find all active tasks where updated_at is greater than cache_version or cache_version is null'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  Task.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:find</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span>@tasks<span style="color:#006600; font-weight:bold;">&#41;</span>
  Task.<span style="color:#9900CC;">update_cache</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This doesn&#8217;t test the search conditions at all. So I moved on to yield:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Task.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:find</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_yield</span>
 received unexpected message <span style="color:#996600;">&quot;active&quot;</span></pre></div></div>

<p>Then I started adding in the expectations:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Task.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:active</span><span style="color:#006600; font-weight:bold;">&#41;</span>
Task.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:find</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_yield</span></pre></div></div>

<p>But how do I know that active is being compared to true? Now I&#8217;d have to use a mock to do that:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">mock_active = mock<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:active</span><span style="color:#006600; font-weight:bold;">&#41;</span>
mock_active.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span>:==<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>
Task.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:active</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_return</span><span style="color:#006600; font-weight:bold;">&#40;</span>mock_active<span style="color:#006600; font-weight:bold;">&#41;</span>
Task.<span style="color:#9900CC;">should_receive</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:find</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">and_yield</span></pre></div></div>

<p>As you can see, this is getting quite painful. So it was time to abstract this out into something more meaningful. I created a class called FindWithSquirrel:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FindWithSquirrel
  <span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#6666ff; font-weight:bold;">Spec::Matchers</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>klass, expected<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@klass</span> = klass
    <span style="color:#0066ff; font-weight:bold;">@expected</span> = expected
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> verify
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And I added a way to gain access to the class:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#9966CC; font-weight:bold;">Class</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> should_receive_squirrel_find_with<span style="color:#006600; font-weight:bold;">&#40;</span>expected<span style="color:#006600; font-weight:bold;">&#41;</span>
    FindWithSquirrel.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span>, expected<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now the new class needs to extend ActiveRecord to override find and record what happens:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FindWithSquirrel
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>klass, expected<span style="color:#006600; font-weight:bold;">&#41;</span>
    ...
    <span style="color:#9900CC;">extend</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>  
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> extend
    <span style="color:#0066ff; font-weight:bold;">@klass</span>.<span style="color:#9900CC;">class_eval</span> <span style="color:#006600; font-weight:bold;">%</span>Q<span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_with_finds</span>
        <span style="color:#0066ff; font-weight:bold;">@find_with_finds</span> <span style="color:#006600; font-weight:bold;">||</span>= <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">find_with_find_with</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args, <span style="color:#006600; font-weight:bold;">&amp;</span>amp;blk<span style="color:#006600; font-weight:bold;">&#41;</span>
        find_with_finds <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; find_without_find_with<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:query</span>, <span style="color:#006600; font-weight:bold;">&amp;</span>amp;blk<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_find_conditions</span>
        find_without_find_with<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args, <span style="color:#006600; font-weight:bold;">&amp;</span>amp;blk<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#0000FF; font-weight:bold;">self</span>
        alias_method <span style="color:#ff3333; font-weight:bold;">:find_without_find_with</span>, <span style="color:#ff3333; font-weight:bold;">:find</span>
        alias_method <span style="color:#ff3333; font-weight:bold;">:find</span>, <span style="color:#ff3333; font-weight:bold;">:find_with_find_with</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So now I&#8217;ve got a variable on the model class holding an array of generated conditions. I can fill in the verify method:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FindWithSquirrel
  <span style="color:#9966CC; font-weight:bold;">def</span> finds
    <span style="color:#0066ff; font-weight:bold;">@klass</span>.<span style="color:#9900CC;">find_with_finds</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> verify
    finds.<span style="color:#9900CC;">should</span> <span style="color:#9966CC; font-weight:bold;">include</span><span style="color:#006600; font-weight:bold;">&#40;</span>@expected<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>That&#8217;s all fine, but now I need to make rspec actually call my verify method. I can do that by reusing the way rspec mocks work. I can do that by adding my class instances to the same array that rspec adds it&#8217;s mock expectations:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FindWithSquirrel
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>klass, expected<span style="color:#006600; font-weight:bold;">&#41;</span>
    ...
    <span style="color:#ff6633; font-weight:bold;">$rspec_mocks</span>.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#ff6633; font-weight:bold;">$rspec_mocks</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now the rspec mock framework is expecting to call the methods &#8216;rspec_verify&#8217; and &#8216;rspec_reset&#8217;, so:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FindWithSquirrel
  alias_method <span style="color:#ff3333; font-weight:bold;">:rspec_verify</span> <span style="color:#ff3333; font-weight:bold;">:verify</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> rspec_reset
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now I can run this spec, and it works great. But it seems to break all the subsequent specs that also use the find function. I have to flesh out that reset function a little. Remember my earlier <em>extend</em> function &#8211; I need to remove my ActiveRecord extensions:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> FindWithSquirrel
  <span style="color:#9966CC; font-weight:bold;">def</span> unextend
    <span style="color:#0066ff; font-weight:bold;">@klass</span>.<span style="color:#9900CC;">class_eval</span> <span style="color:#006600; font-weight:bold;">%</span>Q<span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#0000FF; font-weight:bold;">self</span>
        alias_method <span style="color:#ff3333; font-weight:bold;">:find</span>, <span style="color:#ff3333; font-weight:bold;">:find_without_find_with</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  alias_method <span style="color:#ff3333; font-weight:bold;">:rspec_reset</span>, <span style="color:#ff3333; font-weight:bold;">:unextend</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So what does my spec look like?</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">it <span style="color:#996600;">'should find all active tasks where updated_at is greater than cache_version or cache_version is null'</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  Task.<span style="color:#9900CC;">should_receive_squirrel_find_with</span><span style="color:#006600; font-weight:bold;">&#40;</span>
    <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;(tasks.active = ? AND (tasks.updated_at &amp;gt; tasks.cache_version OR tasks.cache_version IS NULL))&quot;</span>, <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  Task.<span style="color:#9900CC;">update_cache</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So the class is testing that squirrel is outputting the correct conditions. You could argue that squirrel&#8217;s own tests fulfill this testing need, but this class gives a good jumping point to testing that squirrel is receiving the correct parameters. <a href="http://gist.github.com/182070">The full file can be found here</a>. Just include it from your spec_helper.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/squirrel-and-the-custom-nut-matcher/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Choosing which database indexes to add</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/which-database-indexes-to-add/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/which-database-indexes-to-add/#comments</comments>
		<pubDate>Thu, 20 Aug 2009 05:24:19 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=409</guid>
		<description><![CDATA[When writing a Rails application, how do you decide on the best indexes to add to your database? It might seem obvious, especially if you work on a project from scratch. The problem is a little harder when you come to optimize an existing codebase. New Relic Recently I&#8217;ve been using two methods to work [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fwhich-database-indexes-to-add%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fwhich-database-indexes-to-add%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=mysql,rails" height="61" width="50" /><br />
			</a>
		</div>
<p>When writing a Rails application, how do you decide on the best indexes to add to your database? It might seem obvious, especially if you work on a project from scratch. The problem is a little harder when you come to optimize an existing codebase.</p>
<h3>New Relic</h3>
<p>Recently I&#8217;ve been using two methods to work out where to put indexes. Firstly I&#8217;d strongly recommend using <a href="http://www.newrelic.com/">New Relic RPM</a> in development mode. When running your application you can visit /newrelic to get all kinds of useful information. Here you can see the most recent rails calls:</p>
<p style="text-align: center;"><a href="http://www.boost.co.nz/blog/wp-content/uploads/2009/08/Picture-42.png"><img class="size-full wp-image-414 aligncenter" title="Picture 4" src="http://www.boost.co.nz/blog/wp-content/uploads/2009/08/Picture-42.png" alt="Picture 4" width="613" height="112" /></a></p>
<p><span id="more-409"></span>And you can drill down to see the database calls:</p>
<p><a href="http://www.boost.co.nz/blog/wp-content/uploads/2009/08/Picture-8.png"><img class="size-full wp-image-417 aligncenter" title="Picture 8" src="http://www.boost.co.nz/blog/wp-content/uploads/2009/08/Picture-8.png" alt="Picture 8" width="661" height="82" /></a></p>
<p>And then you can drill down further to see a statement analysis. This will give you information like so:</p>
<table border="0">
<tbody>
<tr>
<td>Query</td>
<td>SELECT * FROM `projects` WHERE (`projects`.account_id = 3) ORDER BY position</td>
</tr>
<tr>
<td>Select type</td>
<td>SIMPLE</td>
</tr>
<tr>
<td>Possible Keys</td>
<td></td>
</tr>
<tr>
<td>Key</td>
<td></td>
</tr>
<tr>
<td>Extra</td>
<td>Using where; Using filesort</td>
</tr>
</tbody>
</table>
<p>So this will tell you that there are no keys used, and no possible keys to use. If you now create a migration as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> CreateIndexes <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Migration</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
    add_index <span style="color:#ff3333; font-weight:bold;">:projects</span>, <span style="color:#ff3333; font-weight:bold;">:account_id</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now run the query again after migrating:</p>
<table border="0">
<tbody>
<tr>
<td>Query</td>
<td>SELECT * FROM `projects` WHERE (`projects`.account_id = 3) ORDER BY position</td>
</tr>
<tr>
<td>Select type</td>
<td>SIMPLE</td>
</tr>
<tr>
<td>Possible Keys</td>
<td>index_projects_on_account_id</td>
</tr>
<tr>
<td>Key</td>
<td>index_projects_on_account_id</td>
</tr>
<tr>
<td>Extra</td>
<td>Using where; Using filesort</td>
</tr>
</tbody>
</table>
<p>But we could do better. Notice that in the extra field it says &#8220;Using filesort&#8221;. This means that MySQL is doing a normal sort using the row data. If projects are usually selected by account_id and ordered by position then we have a good case for sorting by index. We can&#8217;t just add an index on the position column as this won&#8217;t be used (try it and you&#8217;ll see exactly the same results). Instead we have to add an index that covers both account_id and position:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">add_index <span style="color:#ff3333; font-weight:bold;">:projects</span>, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:account_id</span>, <span style="color:#ff3333; font-weight:bold;">:position</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Now looking in RPM again you&#8217;ll see things change to:</p>
<table border="0">
<tbody>
<tr>
<td>Query</td>
<td>SELECT * FROM `projects` WHERE (`projects`.account_id = 3) ORDER BY position</td>
</tr>
<tr>
<td>Select type</td>
<td>SIMPLE</td>
</tr>
<tr>
<td>Possible Keys</td>
<td>index_projects_on_account_id_and_position</td>
</tr>
<tr>
<td>Key</td>
<td>index_projects_on_account_id_and_position</td>
</tr>
<tr>
<td>Extra</td>
<td>Using where</td>
</tr>
</tbody>
</table>
<h3>Overriding execute</h3>
<p>I talked about using two tools to work out where to put indexes. New Relic is great and gives lots of useful information, but I wanted to see what queries were running without indexes as the application was used, in order decide if they required optimizing. I placed the following (ugly) snippet of code into the development or staging environment file:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">config.<span style="color:#9900CC;">after_initialize</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:old_execute</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9966CC; font-weight:bold;">class</span>.<span style="color:#9900CC;">class_eval</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      alias_method <span style="color:#ff3333; font-weight:bold;">:old_execute</span>, <span style="color:#ff3333; font-weight:bold;">:execute</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> log_explain<span style="color:#006600; font-weight:bold;">&#40;</span>str<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> str =~ <span style="color:#006600; font-weight:bold;">/</span>^SELECT.<span style="color:#006600; font-weight:bold;">*</span>WHERE<span style="color:#006600; font-weight:bold;">/</span>i
          results = old_execute<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'EXPLAIN %s'</span> <span style="color:#006600; font-weight:bold;">%</span> str<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
          <span style="color:#9966CC; font-weight:bold;">while</span> row = results.<span style="color:#9900CC;">fetch_row</span>
            <span style="color:#9966CC; font-weight:bold;">if</span> row<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">5</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">blank</span>?
              <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/log/sql.log'</span>, <span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>f<span style="color:#006600; font-weight:bold;">|</span>
                f.<span style="color:#CC0066; font-weight:bold;">puts</span> str
                f.<span style="color:#CC0066; font-weight:bold;">puts</span> row.<span style="color:#9900CC;">inspect</span>
              <span style="color:#9966CC; font-weight:bold;">end</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> execute<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
        log_explain<span style="color:#006600; font-weight:bold;">&#40;</span>args.<span style="color:#9900CC;">first</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        old_execute<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>args<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This performs a similar task to RPM in that it runs MySQL&#8217;s <a href="http://dev.mysql.com/doc/refman/5.0/en/explain.html">EXPLAIN</a> statement on each SELECT statement that runs. However, I&#8217;ve set it up to filter out any statements that are already using keys (if row[5].blank?). Now by tailing the file log/sql.log I&#8217;ll be able to see any unindexed queries that are running on the database. I can use this information to quickly run through the whole application to find any problem areas.</p>
<h3>What not to index</h3>
<p>Most of the database calls from a rails application are going to be quite generic, the same thing over and over, and indexing is good in this situation. Some database calls are going to be a little different &#8211; think search, statistical count, etc. You&#8217;ll need to think careful if these require indexes or not, considering how often they&#8217;re run, and how fast they need to be. Caching can be a good replacement in these areas. Also take into account that indexes slow down database writes, and indexes on string columns are going to be much more intensive that indexes on integer columns.</p>
<h3>Load testing</h3>
<p>Of course you might not find all problem areas, or you might not be optimizing the correct queries. These methods should give you a good idea, but they&#8217;re no replacement for doing good load testing on your application. We&#8217;ll be posting more about load testing a rails application in the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/which-database-indexes-to-add/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>DigitalNZ client library for ruby</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/digitalnz-client-library-for-ruby/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/digitalnz-client-library-for-ruby/#comments</comments>
		<pubDate>Thu, 23 Jul 2009 21:56:37 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=279</guid>
		<description><![CDATA[We&#8217;ve just released a new client library for accessing the digitalnz.org&#8217;s search API. This library uses nokogiri for speedily parsing the XML, making it faster than an existing dnz client library using JSON parsing. Installation sudo gem install dnz-client Or for the bleeding edge (if there is one): sudo gem install boost-dnz-client You&#8217;ll need to [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fdigitalnz-client-library-for-ruby%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fdigitalnz-client-library-for-ruby%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=ruby" height="61" width="50" /><br />
			</a>
		</div>
<p>We&#8217;ve just released a <a href="http://github.com/boost/dnz-client">new client library</a> for accessing the <a href="http://digitalnz.org">digitalnz.org&#8217;s</a> search API. This library uses <a href="http://github.com/tenderlove/nokogiri">nokogiri</a> for speedily parsing the XML, making it faster than an <a href="http://github.com/jamesotron/digitalnz/">existing</a> dnz client library using JSON parsing.</p>
<h3>Installation</h3>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> dnz-client</pre></div></div>

<p>Or for the bleeding edge (if there is one):</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">sudo</span> gem <span style="color: #c20cb9; font-weight: bold;">install</span> boost-dnz-client</pre></div></div>

<p>You&#8217;ll need to have an API key from <a href="http://digitalnz.org">digitalnz.org</a><br />
<span id="more-279"></span></p>
<h3>Examples</h3>
<h4>Simple search</h4>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'dnz/client'</span>
&nbsp;
client = <span style="color:#6666ff; font-weight:bold;">DNZ::Client</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'api_key'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
search = client.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'otago'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
search.<span style="color:#9900CC;">results</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>result<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> result.<span style="color:#9900CC;">title</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><strong>Fetch all categories</strong></p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'dnz/client'</span>
&nbsp;
client = <span style="color:#6666ff; font-weight:bold;">DNZ::Client</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'api_key'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
categories = client.<span style="color:#9900CC;">categories</span>
&nbsp;
categories.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>category<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Category %s has %d results&quot;</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#006600; font-weight:bold;">&#91;</span>category.<span style="color:#9900CC;">name</span>, category.<span style="color:#9900CC;">count</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h4>Fetch a facet</h4>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'dnz/client'</span>
&nbsp;
client = <span style="color:#6666ff; font-weight:bold;">DNZ::Client</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'api_key'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
search = client.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'otago'</span>, <span style="color:#ff3333; font-weight:bold;">:facets</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'category'</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
search.<span style="color:#9900CC;">facets</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'category'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>category<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">'Search for otago has %d items in category %s'</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#006600; font-weight:bold;">&#91;</span>category.<span style="color:#9900CC;">count</span>, category.<span style="color:#9900CC;">name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/digitalnz-client-library-for-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Writing tests/specs for existing code</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/writing-testsspecs-for-existing-code/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/writing-testsspecs-for-existing-code/#comments</comments>
		<pubDate>Mon, 22 Jun 2009 00:22:38 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=201</guid>
		<description><![CDATA[On several occasions we&#8217;ve looked at Rails projects with no tests, or very low test coverage. Trying to write tests when you didn&#8217;t write the original methods is difficult. Here are some tips that we&#8217;ve found useful. Use your favourite framework. If there is a large body of existing tests using a particular framework, write [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fwriting-testsspecs-for-existing-code%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fwriting-testsspecs-for-existing-code%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=rspec,ruby,tdd,testing" height="61" width="50" /><br />
			</a>
		</div>
<p>On several occasions we&#8217;ve looked at Rails projects with no tests, or very low test coverage. Trying to write tests when you didn&#8217;t write the original methods is difficult. Here are some tips that we&#8217;ve found useful.</p>
<h3>Use your favourite framework.</h3>
<p>If there is a large body of existing tests using a particular framework, write your new tests in that framework. If there are few or no tests then strip out anything already there and replace it with your preferred framework. At Boost we&#8217;ve decided to use <a href="http://rspec.info">RSpec</a> for all our projects. Your objective here is to write tests, not to learn a new way of writing tests.<span id="more-201"></span></p>
<h3>Don&#8217;t fix bugs!</h3>
<p>If you discover what you believe to be a bug while writing tests, consider that you don&#8217;t know why the bug is there. You should write your test to pass the code <em>as is</em>. Describe the bug in your bug tracker and move on. I&#8217;ve fixed bugs while writing tests only to find that the side effect breaks something else &#8211; but I had no tests so there was no way to know.</p>
<h3>Start with the basics</h3>
<p>The easiest way to get started is to write a test for every method, action and view that just runs without asserting anything. This will get your test coverage up. Running over the whole code base allows you to catch exceptions caused by typos. Doing this will also give you a good starting overview of the code base. Using a tool like <a href="http://www.zenspider.com/ZSS/Products/ZenTest/">ZenTest</a>, or a recently posted rake task <a href="http://github.com/internuity/unspecd">unspec&#8217;d</a>, will help find everything to test.</p>
<h3>Mocks and Stubs</h3>
<p>Obviously you&#8217;ll be using mocks and stubs, but be careful not to stub out too much. Get a test in for every public method, and don&#8217;t stub out private methods.</p>
<h3>Test your own code</h3>
<p>Make sure that you write comprehensive tests for any code <em>you</em> add to the project. Never use the lack of existing tests as an excuse for not writing your own.</p>
<p>Any finally, don&#8217;t give up hope! For any reasonably complex project it is nearly always faster to implement the tests/specs than to rewrite the whole thing from scratch. Writing tests is actually a really good way to learn a foreign code base.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/writing-testsspecs-for-existing-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extracting Active Directory SIDs with Ruby</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/extracting-active-directory-sids-with-ruby/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/extracting-active-directory-sids-with-ruby/#comments</comments>
		<pubDate>Wed, 29 Apr 2009 04:46:15 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[active directory]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://www.boost.co.nz/blog/?p=137</guid>
		<description><![CDATA[Getting user and group information from Active Directory via LDAP is nearly easy, but I came across one hurdle. If you retrieve a user, you might get something like this: &#123; :smaccountname =&#38;gt; &#91;'jeremy'&#93;, :dn =&#38;gt; ‘&#91;&#34;CN=Jeremy Wells,CN=Users,DC=domain,DC=boost,DC=co,DC=nz&#34;&#93;, :primarygroupid =&#38;gt; &#91;'1114'&#93;, :objectsid =&#38;gt; &#91;&#34;010500000000000525000000\210B ?\23302r\255ոT040000&#34;&#93; &#125; If you then wanted to get the users primary [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fextracting-active-directory-sids-with-ruby%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fextracting-active-directory-sids-with-ruby%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly&amp;hashtags=active+directory,ruby,windows" height="61" width="50" /><br />
			</a>
		</div>
<p>Getting user and group information from Active Directory via LDAP is nearly easy, but I came across one hurdle. If you retrieve a user, you might get something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff3333; font-weight:bold;">:smaccountname</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'jeremy'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:dn</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; ‘<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;CN=Jeremy Wells,CN=Users,DC=domain,DC=boost,DC=co,DC=nz&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:primarygroupid</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'1114'</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:objectsid</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;010500000000000525000000<span style="color:#000099;">\2</span>10B ?<span style="color:#000099;">\2</span>3302r<span style="color:#000099;">\2</span>55ոT040000&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>If you then wanted to get the users primary group, you&#8217;d need to search using that primary group id. But you&#8217;d find there is no corresponding id on the group object, which looks as thus:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#ff3333; font-weight:bold;">:samaccountname</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Students&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:dn</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;CN=Students,OU=Groups,DC=domain,DC=boost,DC=co,DC=nz&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:objectsid</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;010500000000000525000000<span style="color:#000099;">\2</span>10B ?<span style="color:#000099;">\2</span>3302r<span style="color:#000099;">\2</span>55ոZ040000&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
  <span style="color:#ff3333; font-weight:bold;">:name</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;Students&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>But notice the binary field :objectsid. This is the binary form of the string you may see sometimes when using AD, called SID, and it looks something like &#8220;S-1-5-21-123-456-789&#8243;. In order to find the users group you would take the :primarygroupid and the users :objectsid to generate the groups SID.</p>
<div id="attachment_151" class="wp-caption alignnone" style="width: 510px"><a href="http://www.boost.co.nz/blog/wp-content/uploads/2009/04/sid1b32.jpg"><img class="size-full wp-image-151" src="http://www.boost.co.nz/blog/wp-content/uploads/2009/04/sid1b32.jpg" alt="Space Intruder Detector (SID)" width="500" height="350" /></a><p class="wp-caption-text">Space Intruder Detector (SID) UFO © ITV Global Entertainment </p></div>
<p><span id="more-137"></span></p>
<p>Only the last group of numbers in the SID corresponds to the current object, so to find the SID for another object we can just take off the last number group and replace it with the :primarygroupid, 1114. However, first we need to convert the binary string into a SID string.</p>
<p>The binary form of the SID is as follows:</p>
<ul>
<li>byte 1: SID structure revision (always 1, but it could change in the future). This becomes the first number group.</li>
<li>byte 2: The number of sub-authorities in the SID. This is discarded for the string, but you can use it to work out the number of number groups ahead.</li>
<li>byte 3 &#8211; 9: Identifier Authority. This field should be converted to hexadecimal as the second number group.</li>
<li>byte 10 onwards: A variable length list of unsigned 32bit integers, the number of which is defined in byte 2.</li>
</ul>
<p>Here is ruby code for doing the conversion:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> get_sid_string<span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#41;</span>
  sid = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  sid <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; data<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</span>
&nbsp;
  rid = <span style="color:#996600;">&quot;&quot;</span>
  <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">6</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">downto</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>i<span style="color:#006600; font-weight:bold;">|</span>
    rid <span style="color:#006600; font-weight:bold;">+</span>= byte2hex<span style="color:#006600; font-weight:bold;">&#40;</span>data<span style="color:#006600; font-weight:bold;">&#91;</span>i,<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
  sid <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; rid.<span style="color:#9900CC;">to_i</span>.<span style="color:#9900CC;">to_s</span>
&nbsp;
  sid <span style="color:#006600; font-weight:bold;">+</span>= data.<span style="color:#9900CC;">unpack</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;bbbbbbbbV*&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>8..<span style="color:#006600; font-weight:bold;">-</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#996600;">&quot;S-&quot;</span> <span style="color:#006600; font-weight:bold;">+</span> sid.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'-'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> byte2hex<span style="color:#006600; font-weight:bold;">&#40;</span>b<span style="color:#006600; font-weight:bold;">&#41;</span>
  ret = <span style="color:#996600;">'%x'</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#006600; font-weight:bold;">&#40;</span>b.<span style="color:#9900CC;">to_i</span> <span style="color:#006600; font-weight:bold;">&amp;</span>amp; 0xff<span style="color:#006600; font-weight:bold;">&#41;</span>
  ret = <span style="color:#996600;">'0'</span> <span style="color:#006600; font-weight:bold;">+</span> ret <span style="color:#9966CC; font-weight:bold;">if</span> ret.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#006666;">2</span>
  ret
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><em>Note: Originally I was using unpack with L* instead of V*. My tests were passing fine on my machine, but not on our CI server. As it turns out the endiness of L is dependent on the processor, and the CI is an old PPC G4.</em></p>
<p>Using the SID string you can now do an LDAP search with Net::LDAP::Filter.eq(&#8220;objectSID&#8221;, sid_string) to find the user. Replace the last number group with that from :primarygroupid and it&#8217;ll find the group. So if the user SID is S-1-5-21-123-456-789 and the :primarygroupid is 1114, the group&#8217;s SID will be S-1-5-21-123-456-1114.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/extracting-active-directory-sids-with-ruby/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JRuby presentation for WellRailed</title>
		<link>http://www.boost.co.nz/blog/ruby-on-rails/jruby-presentation-for-wellrailed/</link>
		<comments>http://www.boost.co.nz/blog/ruby-on-rails/jruby-presentation-for-wellrailed/#comments</comments>
		<pubDate>Thu, 19 Mar 2009 20:28:43 +0000</pubDate>
		<dc:creator>jeremy</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://boost.co.nz/blog/?p=32</guid>
		<description><![CDATA[On the 25th of February &#8217;09 I did a brief JRuby presentation on JRuby and how we&#8217;re using it at Boost. We&#8217;re really excited about some of the capabilities of JRuby. We&#8217;re running a client deployment on Tomcat fronted by IIS, and it was really easy to get everything set up. We wanted to try [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fjruby-presentation-for-wellrailed%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.boost.co.nz%2Fblog%2Fruby-on-rails%2Fjruby-presentation-for-wellrailed%2F&amp;source=boostnewmedia&amp;style=normal&amp;service=bit.ly" height="61" width="50" /><br />
			</a>
		</div>
<p>On the 25th of February &#8217;09 I did a brief JRuby <a href="http://boost.co.nz/blog/wp-content/uploads/2009/03/jruby1.pdf">presentation</a> on JRuby and how we&#8217;re using it at Boost. We&#8217;re really excited about some of the capabilities of JRuby.</p>
<p>We&#8217;re running a client deployment on Tomcat fronted by IIS, and it was really easy to get everything set up. We wanted to try another deployment on <a href="http://glassfish.dev.java.net">Glassfishv3</a> with no webserver in front. Unfortunately (and glassfishv3 is still in development) there were two barriers that prevented us doing so <span id="more-32"></span>:</p>
<ul>
<li>Exessive memory consumption: 2 rails apps + the admin interface = more than a 1G slice could handle.</li>
<li>SSL: I was so close to getting this working, but several hours of working on this is too much, it should be easier.</li>
</ul>
<p>In conclusion, JRuby isn&#8217;t quite ready for our in house projects where we control the deployment, but it is great for Windows deployments. We&#8217;ll keep an eye on it. <a href="http://jruby.codehaus.org/">JRuby 1.2</a> was released just a few days ago with performance increases.</p>
<p>Download the <a href="http://boost.co.nz/blog/wp-content/uploads/2009/03/jruby1.pdf">presentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.boost.co.nz/blog/ruby-on-rails/jruby-presentation-for-wellrailed/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
