<?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>Transcending Frontiers &#187; Introducing Has Face for Rails</title>
	<atom:link href="http://blog.thefrontiergroup.com.au/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.thefrontiergroup.com.au</link>
	<description>Your peek inside the collective mind of The Frontier Group</description>
	<lastBuildDate>Mon, 02 Apr 2012 04:32:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>Introducing Has Face for Rails</title>
		<link>http://blog.thefrontiergroup.com.au/2011/07/introducing-has-face-for-rails/</link>
		<comments>http://blog.thefrontiergroup.com.au/2011/07/introducing-has-face-for-rails/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 01:49:17 +0000</pubDate>
		<dc:creator>Mario Visic</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rubygems]]></category>

		<guid isPermaLink="false">http://blog.thefrontiergroup.com.au/?p=1742</guid>
		<description><![CDATA[Have you ever created an application where users are trusted to upload their own avatars? Wouldn&#8217;t it be great if there was an easy way to ensure the avatar contains a person&#8217;s face? Has Face is a neat little gem that uses the face.com API to ensure that an image contains a persons face. It&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>Have you ever created an application where users are trusted to upload their own avatars? Wouldn&#8217;t it be great if there was an easy way to ensure the avatar contains a person&#8217;s face?</p>
<p><a href="https://github.com/mariovisic/has_face">Has Face</a> is a neat little gem that uses the <a href="http://face.com">face.com API</a> to ensure that an image contains a persons face. It&#8217;s very simple to use and can be easily integrated into an existing rails application.</p>
<p>To get started add the has_face gem to your Gemfile and run a bundle install
<p class="gist-block" data-gist-id="1103591" data-gist-file="Gemfile" id="gist-1103591">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/1103591">View it on Github!</a></p>
<p>Run the generator to copy over an initializer: </p>
<p class="gist-block" data-gist-id="1103591" data-gist-file="install" id="gist-1103591">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/1103591">View it on Github!</a></p>
<p>The initializer should look something like this:</p>
<p class="gist-block" data-gist-id="1103591" data-gist-file="initializer.rb" id="gist-1103591">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/1103591">View it on Github!</a></p>
<p>Now we&#8217;ll need to make a face.com developer account. You can <a href="http://developers.face.com/signup/?g">signup for a free account over at face.com</a>. Once you have signed up, place your API key and API secret in the initializer config.</p>
<p>The last option in the initializer (skip_validation_on_error) will change the behavior of has_face when an error occurs. If set to true, when an error occurs a warning will be logged to the logfile with detailed information about the failure and face validation will be skipped. This can be useful if you want your application to function if the API service is not reachable. If the value is false then an exception will be raised when an API call fails, this will allow you to manually handle the exception yourself, please check the documentation for details on the errors raised.</p>
<p>Once the initializer settings are setup then we can add face validation to a model. In the example below I&#8217;m using carrierwave to attach the image to the model but other image attachment gems should also work fine (anything that correctly responds to `path` should be OK).</p>
<p class="gist-block" data-gist-id="1103591" data-gist-file="user.rb" id="gist-1103591">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/1103591">View it on Github!</a></p>
<p>That&#8217;s it, that&#8217;s all we need to have a functioning face validator. There are a few other options that I haven&#8217;t covered here in this short guide, please <a href="https://github.com/mariovisic/has_face">consult the readme</a> for more detailed information.</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2011/07/introducing-has-face-for-rails/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2011/07/introducing-has-face-for-rails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Simple Database Export and Import With Character Encoding Conversion</title>
		<link>http://blog.thefrontiergroup.com.au/2011/05/simple-db-export-and-import-with-character-encoding-conversion/</link>
		<comments>http://blog.thefrontiergroup.com.au/2011/05/simple-db-export-and-import-with-character-encoding-conversion/#comments</comments>
		<pubDate>Wed, 25 May 2011 12:31:56 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.thefrontiergroup.com.au/?p=1575</guid>
		<description><![CDATA[There is a gem called ydd that offers really simple import and export of smallish databases. It exports to YAML and then imports to whatever database Rails can connect to. After using YDD a few times I&#8217;ve found it easier to pinpoint the cause of problems that occur using taps. It doesn&#8217;t handle character encodings [...]]]></description>
			<content:encoded><![CDATA[<p>There is a gem called <a href="https://github.com/YouthTree/ydd">ydd</a> that offers really simple import and export of smallish databases. It exports to YAML and then imports to whatever database Rails can connect to. After using YDD a few times I&#8217;ve found it easier to pinpoint the cause of problems that occur using <a href="https://github.com/ricardochimal/taps">taps</a>.</p>
<p>It doesn&#8217;t handle character encodings though so I went about adding that. With the handy rchardet gem and IConv, detecting the character encoding of the incoming string and converting it to UTF-8 was pretty simple. I&#8217;ve created a <a href="https://github.com/YouthTree/ydd/pull/3">pull request</a> for the gem that will hopefully be accepted.</p>
<p>The essential code is below, and revolves mainly around the detection and conversion. Using //TRANSLIT causes IConv to try and convert the incoming character code to something that exists in the UTF8 character set, and then //IGNORE will ignore any characters that don&#8217;t exist in the UTF8 character set. Chaining //TRANSLIT and then //IGNORE will make IConv try a conversion first and then ignore anything it cannot convert.</p>
<p><script src="https://gist.github.com/990410.js?file=changes.rb"> </script></p>
<p>I used this gem after the above changes to convert about 400,000 records of text data with ASCII, windows-1252, IBM866 and other character encodings from an old SQLite installation to a new postgres database without any issues.</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2011/05/simple-db-export-and-import-with-character-encoding-conversion/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2011/05/simple-db-export-and-import-with-character-encoding-conversion/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Sending Apple Push notifications in rails with Redis and apn_sender</title>
		<link>http://blog.thefrontiergroup.com.au/2011/05/sending-apple-push-notifications-in-rails-with-redis-and-apn_sender/</link>
		<comments>http://blog.thefrontiergroup.com.au/2011/05/sending-apple-push-notifications-in-rails-with-redis-and-apn_sender/#comments</comments>
		<pubDate>Wed, 11 May 2011 05:39:58 +0000</pubDate>
		<dc:creator>Mario Visic</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Inside TFG]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iOS]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.thefrontiergroup.com.au/?p=1363</guid>
		<description><![CDATA[Sending iOS push notifications from a Rails application is very easy to do these days, thankfully there are many great Ruby gems that can be used to handle most of the magic for you. Recently I ran into the apn_sender gem which handles sending push notifications in a really neat way. Sending push notifications directly [...]]]></description>
			<content:encoded><![CDATA[<p>Sending iOS push notifications from a Rails application is very easy to do these days, thankfully there are many great Ruby gems that can be used to handle most of the magic for you. Recently I ran into the <a href="https://github.com/kdonovan/apn_sender">apn_sender</a> gem which handles sending push notifications in a really neat way.</p>
<p>Sending push notifications directly from a Rails application can be slow and we probably don&#8217;t want to have the user waiting until the notification is sent, instead apn_sender can be setup to run a worker which is constantly connected to the apple push notification service. When there are new notifications to send, the notifications are queued up and sent through the always open connection that is maintained by the worker.</p>
<p>apn_sender uses <a href="http://redis.io/">redis</a> as a message queue to keep track of the notifications waiting to be sent, you&#8217;ll need to install it before using the gem.</p>
<p>To add apn_sender in your Rails 3 application, just add the gem to your Gemfile. We&#8217;re going to need the daemons gem too so we&#8217;ll include that as well.</p>
<p class="gist-block" data-gist-id="965976" data-gist-file="Gemfile" id="gist-965976">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/965976">View it on Github!</a></p>
<p>Now we can create our daemon which we will be using for sending push notifications, this can be placed anywhere, I&#8217;ve put mine in script/apn_sender. Make sure to add execute permission to the file after creating so we can run it.</p>
<p class="gist-block" data-gist-id="965976" data-gist-file="apn_sender.rb" id="gist-965976">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/965976">View it on Github!</a></p>
<p>Before the daemon can start running we&#8217;ll need to put our iOS push certificate into the application. Instructions for generating the certificates are available at the <a href="http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ProvisioningDevelopment/ProvisioningDevelopment.html#//apple_ref/doc/uid/TP40008194-CH104-SW1">Apple Developer site</a>. The certificates need to be placed inside of /config/certs and should be named <i>apn_development.pem</i> or <i>apn_production.pem</i> for production.</p>
<p>Once the certificates are in their correct locations, we can start up the daemon. The daemon does not know about the Rails environment so we need to specify this when starting it up. The daemon supports <i>start</i>, <i>stop</i> and <i>restart</i> commands. There is a verbose flag available to output more information (which can be helpful when debugging).</p>
<p class="gist-block" data-gist-id="965976" data-gist-file="start_command.bash" id="gist-965976">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/965976">View it on Github!</a></p>
<p>Our application is now set up to send push notifications, this can now easily be performed by adding a new notification to the queue. The notify method on the APN class will take a push notification token and then our parameters, we can specify the alert message to show the user, whether or not we want sound as well as the number to display on the badge icon. Anything else we pass to notify will be sent as metadata in the push notification. Here&#8217;s an example of creating a notification.</p>
<p class="gist-block" data-gist-id="965976" data-gist-file="notify.rb" id="gist-965976">Can&rsquo;t see this Gist? <a rel="nofollow" href="http://gist.github.com/965976">View it on Github!</a></p>
<p>The worker should pick up the notification within a few seconds and send it off. The apn_sender has many other features that I haven&#8217;t covered, you can view the full documentation over at <a href="https://github.com/kdonovan/apn_sender">https://github.com/kdonovan/apn_sender</a>.</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2011/05/sending-apple-push-notifications-in-rails-with-redis-and-apn_sender/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2011/05/sending-apple-push-notifications-in-rails-with-redis-and-apn_sender/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>How to Get All Associations for an Activerecord Model</title>
		<link>http://blog.thefrontiergroup.com.au/2011/01/how-to-get-all-associations-for-an-activerecord-model/</link>
		<comments>http://blog.thefrontiergroup.com.au/2011/01/how-to-get-all-associations-for-an-activerecord-model/#comments</comments>
		<pubDate>Wed, 05 Jan 2011 02:54:16 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Inside TFG]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[Reflection]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/2011/01/how-to-get-all-associations-for-an-activerecord-model/</guid>
		<description><![CDATA[There was a question that was asked on our IRC channel today about how to get all the associations for an Activerecord model. I&#8217;m assuming it was to do some debugging or something, in any case I did a bit of digging around in the Rails docs and it turns out the answer isn&#8217;t that [...]]]></description>
			<content:encoded><![CDATA[<p>There was a question that was asked on our IRC channel today about how to get all the associations for an Activerecord model. I&#8217;m assuming it was to do some debugging or something, in any case I did a bit of digging around in the Rails docs and it turns out the answer isn&#8217;t that hard. </p>
<p>Doing something like : </p>
<pre>
    Model.reflect_on_all_associations
</pre>
<p>Will give you all the associations for that model, it&#8217;s pretty dirty though and so an easy way to tidy it up is : </p>
<pre>
    Model.reflect_on_all_associations.collect{ |association|
        association.name.to_s.classify
    }
</pre>
<p>So, as usual with Rails it was easy as pie, I just am putting this here for future use :) </p>
<p>Edit : Thanks to Darcy for tidying up my previous mess :P</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2011/01/how-to-get-all-associations-for-an-activerecord-model/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2011/01/how-to-get-all-associations-for-an-activerecord-model/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A brief introduction to the RVM Ruby API</title>
		<link>http://blog.thefrontiergroup.com.au/2010/12/a-brief-introduction-to-the-rvm-ruby-api/</link>
		<comments>http://blog.thefrontiergroup.com.au/2010/12/a-brief-introduction-to-the-rvm-ruby-api/#comments</comments>
		<pubDate>Tue, 14 Dec 2010 02:23:51 +0000</pubDate>
		<dc:creator>Darcy Laycock</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/?p=1107</guid>
		<description><![CDATA[<p>As part of the work done on rvm during the Ruby Summer of Code, One of the
things I worked to add was a fairly comprehensive ruby version of the bash api.</p>

<p>Since then, the ruby api has been used to build a couple of small projects
and tools but it still maintains relatively undocumented.</p>

<p>Today, I&#8217;m going to introduce the basics of working with the ruby api, starting
by introducing the fundamental concepts you need to know and then going on to
cover how the most common example of it&#8217;s use (rvm gemset support in passenger)
works under the hood.</p>]]></description>
			<content:encoded><![CDATA[<p>As part of the work done on <a title="RVM" href="http://rvm.beginrescueend.com">RVM</a> during the <a title="Ruby Summer of Code" href="http://rubysoc.org">Ruby Summer of Code</a>, One of the things I worked to add was a fairly comprehensive Ruby version of the bash API.</p>
<p>Since then, the Ruby API has been used to build a couple of small projects and tools but it still maintains relatively undocumented.</p>
<p>Today, I’m going to introduce the basics of working with the Ruby API, starting by introducing the fundamental concepts you need to know and then going on to cover how the most common example of it’s use (rvm gemset support in passenger) works under the hood.</p>
<h2 id="getting_started">Getting started</h2>
<p>First off, you’re going to want to make sure you actually have the Ruby API installed. If you have a remotely recent (e.g. newer than 6 or so months) copy of rvm, you’ll already have a copy &#8211; Otherwise, you’re going to need to update your rvm install using <code>rvm update</code>.</p>
<p>To load the API, open up irb and type the following:</p>
<pre><code># First, find where rvm is installed
rvm_path = File.expand_path(ENV['rvm_path'] || '~/.rvm')
# Secondly, add the ruby library to the load path
$LOAD_PATH.unshift File.join(rvm_path, 'lib')
# Finally, actually load rvm
require 'rvm'
</code></pre>
<p>Once said code has been executed, you should have access to <code>RVM</code> constant in your irb session. The method we use to require it means that it is loaded from the currently installed version of rvm so you don’t have to deal with issues related to different versions between rvm itself and the Ruby API.</p>
<h2 id="the_bare_basics">The bare basics</h2>
<p>The ruby api works on the concept of a rvm ‘environment’ &#8211; Essentially, you can think of them as the equivalent of a shell instance &#8211; They keep track of instance variables, have their own ruby / gemset  selection and are sandboxed (for the most part) from other environments. Creating a new environment is as simple as doing the following in your ruby code:</p>
<pre><code>env = RVM.environment 'ree'
</code></pre>
<p>Or, alternatively, you can pass a block and it will be called with the environment as an argument. Along side this, you have <code>RVM.environments</code>, which accepts multiple ruby names and calls the block with each environment.</p>
<p>For convenience sake, RVM exposes <code>RVM.current</code>, an environment that defaults to the currently loaded gemset (e.g. if you open irb in <code>rbx@rails3</code>, it will be an environment using <code>rbx@rails3</code>).</p>
<p>As an added bonus, when you call an undefined method on <code>RVM</code>, we automatically use method missing to call it on <code>RVM.current</code> &#8211; Hence, If <code>RVM::Environment#some_instance_method </code>exists, you can use <code>RVM.some_instance_method</code> to call it in the current environment object.</p>
<h2 id="working_with_environments">Working with environments</h2>
<p>So, now that you know how to get environment object, you need to know how to use it. In the simplest form, the Ruby API mirrors the command line program by translating:</p>
<pre><code>rvm command action arg1 arg2
</code></pre>
<p>Into:</p>
<pre><code>env.command_action arg1, arg2
</code></pre>
<p>With the library automatically taking care of converting arguments (e.g. a hash as the last value will be converted to arguments to the program).</p>
<p>As an example, to call <code>rvm list strings</code>, One would use <code>env.list_strings</code>. Likewise, <code>rvm use</code> becomes <code>env.use</code> and so on and so forth. In these cases, use switches the environments ruby &#8211; not the running ruby itself.</p>
<p>One of the added features in the Ruby API is that <code>use</code> and <code>gemset_use</code> have alternatives with a bang (<code>use!</code> and <code>gemset_use!</code>) that will switch the currently loaded ruby’s gemset (by changing <code>GEM_PATH</code> and <code>GEM_HOME</code> and then telling rubygems about the change) - raising an exception if it’s for a different ruby installation. This switch makes it possibly to dynamically switch your ruby applications gemset whilst running.</p>
<p>Of course, dealing with a direct port of the API isn’t always nice when you’re writing a lot of code <code>env.alias_list</code> feels clunky compared to most ruby code and some of the tools are rough around the edges. With this in mind, the ruby api offers wrappers for situations where this becomes noticeable, e.g <code>env.aliases</code> will return a more ruby-like wrapper for the alias command that lets you do things such as <code>env.alias.all</code>, <code>env.aliases.create</code> and so on. In some cases (e.g. <code>env.list_*</code>), the wrappers add features (such as expanding strings) that aren’t found in the bash API via the wrapper.</p>
<h2 id="a_real_world_example">A real world example</h2>
<p>With that said and done, it’s time to look at a real world example. In this case, the most commonly-used example of the rvm ruby API &#8211; A use of passengers support for a <code>config/setup_load_paths.rb</code> file which lets passenger automatically load <code>.rvmrc</code> files. When a compatible ruby is detected, the file will automatically switch the gemset on the fly &#8211; In essence, letting passenger work with the one-gemset-per-application philosophy we advocate when dealing with rvm.</p>
<p>For references sake, the rvm portion of the code is:</p>
<pre><code>if ENV['MY_RUBY_HOME'] &amp;&amp; ENV['MY_RUBY_HOME'].include?('rvm')
  begin
    rvm_path     = File.dirname(File.dirname(ENV['MY_RUBY_HOME']))
    rvm_lib_path = File.join(rvm_path, 'lib')
    $LOAD_PATH.unshift rvm_lib_path
    require 'rvm'
    RVM.use_from_path! File.dirname(File.dirname(__FILE__))
  rescue LoadError
    # RVM is unavailable at this point.
    raise "RVM ruby lib is currently unavailable."
  end
end
</code></pre>
<p>Line by line, this code essentially:</p>
<ol>
<li>Checks that we’re loading it in an RVM ruby &#8211; rvm always sets the <code>MY_RUBY_HOME</code> environment variable when using wrappers and we ensure that “rvm” is part of said variables value.</li>
<li>It begins a begin-rescue-end section of code to load rvm &#8211; Giving us a nice error message if rvm isn’t available.</li>
<li>Based on my ruby home, We find the location of your rvm install (as <code>rvm_path </code>may or may not be set at this point).</li>
<li>We add the rvm ruby lib directory to the load path</li>
<li>We require the API</li>
</ol>
<p>Up until this point, it is almost exactly like our original example. Where it differs is the next line:</p>
<pre><code>RVM.use_from_path! File.dirname(File.dirname(__FILE__))
</code></pre>
<p>Knowing what I wrote about earlier, we know this is the same as:</p>
<pre><code>RVM.current.use_from_path! File.dirname(File.dirname(__FILE__))
</code></pre>
<p>Which, if we look under the hood, does:</p>
<pre><code>RVM.current.use! RVM.current.tools.path_identifier(path)
</code></pre>
<p>Expanding this again using what we learnt earlier, we know that <code>RVM.current.use! </code>will take a given ruby string (e.g. <code>ree@rails3</code>) and attempt to switch out the gemset when the ruby versions match. Continuing on, we know <code>RVM.current.tools.path_identifier </code>is roughly the same as <code>RVM.current.tools_path_identifier</code> &#8211; a line which takes a path and, taking into account .rvmrc files, returns the identifier (e.g. <code>ree@rails3</code>) we’d get if we had changed into the given directory from the command line.</p>
<p>Putting it all together, the ruby api essentially just finds out which identifier the given path should use (by loading a projects <code>.rvmrc</code> in the given environment), checks they’re for the same ruby install (to avoid issues with binary gems) and finally switches out the <code>GEM_HOME</code> and <code>GEM_PATH</code> variables for the current process, letting your application use a different gemset.</p>
<p>In short, under the hood it simple finds out the gemset details and updates your application to switch them out similar to how rvm would from the command line.</p>
<h2 id="more_examples">More examples</h2>
<p>We’ve only covered the basics of of the ruby api &#8211; For the most part, everything implemented in the bash API is supposed to be (except where it lags behind in terms of updates) exposed via the Ruby API in a simple, consistent manner. In practice, this has primarily been used for things like <a href="https://github.com/tomas-stefano/infinity_test">infinity_test</a> and <a href="http://www.metaskills.net/2010/7/30/the-rvm-ruby-api">various CI-related work</a> which make working with multiple rubies easier from ruby applications.</p>
<p>I’d ultimately love to see it used more for tools built around rvm &#8211; e.g. a web interface for managing a servers system wide install and exposing it over HTTP. Lastly, because it’s written in Ruby, if you’ve ever wanted to contribute to rvm but have felt apprehensive due to the fact it’s written in shell script, the rvm ruby API is a good place to start.</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2010/12/a-brief-introduction-to-the-rvm-ruby-api/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2010/12/a-brief-introduction-to-the-rvm-ruby-api/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>RVM: More than Ruby 1.9 and Rails 3</title>
		<link>http://blog.thefrontiergroup.com.au/2010/09/rvm-more-than-ruby-1-9-and-rails-3/</link>
		<comments>http://blog.thefrontiergroup.com.au/2010/09/rvm-more-than-ruby-1-9-and-rails-3/#comments</comments>
		<pubDate>Thu, 30 Sep 2010 04:12:11 +0000</pubDate>
		<dc:creator>Darcy Laycock</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips and Tricks]]></category>
		<category><![CDATA[Websites or Tools]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[rvm]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/?p=1021</guid>
		<description><![CDATA[RVM is best known as a tool to help developers upgrade their applications to newer versions of Ruby and Rails (3 specifically). That said, for ruby developers, it has many features which help to make their workflow far simpler. Whilst some have shown with effort and rigorous manual process you can achieve much of what [...]]]></description>
			<content:encoded><![CDATA[<p>RVM is best known as a tool to help developers upgrade their applications to newer versions of Ruby and Rails (3 specifically). That said, for ruby developers, it has many features which help to make their workflow far simpler. Whilst some have shown with effort and rigorous manual process you can achieve much of what RVM offers, the following is a look into some less often discussed areas of RVM that make it my most favoured tool when it comes to development.</p>
<h2 id="gemsets_and_the_gemset_hierarchy">Gemsets and the Gemset Hierarchy</h2>
<p>Whilst Bundler solves most of the problems related to isolating gems for me personally, on most projects I develop for there are things that make rvm&#8217;s implementation of gemsets (especially when used along with bundler) invaluable to me as a ruby developer.</p>
<h3 id="isolating_gems">Isolating Gems</h3>
<p>A major strength of RVM is the ability to isolate gems at the system level. This keeps them safely partitioned from any other gems unrelated to my project. The way bundler isolates gems is for the most part at run time &#8211; It changes the way rubygems works to solve it&#8217;s problem and either installs all gems to a user specified path or to your gem directory.</p>
<p>If you are using the usr specified path option, you must to remember that your custom rubygems bin directory is not contained in your PATH. This means that you must either manually add it to the PATH,  or your need to manually prefix each command with bundle exec, or alternatively you can generate the binaries into your applications bin directory and each command with ./bin/</p>
<p>If you take the opposite approach and install your gems into your gem home, you then need to be aware of the fact that each next install will overwrite any previous binaries &#8211; the canonical example being Rails 2 and Rails 3. The way that rubygems generates binaries lets you run <code>gem-binary-name _version_ something</code> to call the binary loaded from a specified gem version. Unfortunately, in Rails 3, the rails binary was moved from the rails gem into the railties gem which just so happens to break this feature of rubygems. You can try this for yourself on a new rvm gemset, install rails 2.3.8 and rails 3.0.0 and then try <code>rails _2.3.8_ -v</code>.  If you are using the simple solution of installing to gem home, even though you are using bundler it will still overwrite the binary.</p>
<p>One common suggestion is to just create a wrapper binary manually (e.g. rails2) or always prefix your commands with bundle exec. In contrast RVM&#8217;s isolation works by explicitly setting rubygems home and path to directories isolated under RVM. RVM takes this even further using gemsets (think subdirectories) to handle more fine grain isolation. For example, I personally use 1 gemset per application, thus avoiding the issues described above as for each application I will have only a single version of rails installed. Even better, switching is shell-local and only persists for a single shell instance. This means that I can have two different applications with two completely different versions of Rails running at the same time in different terminal sessions without issue.</p>
<p>As an added bonus, because RVM isolates at the rubygems system level (using environment variables), your application doesn&#8217;t actually need to know or care about conflicts from gems that the application does not use.</p>
<p>Combining RVM and Bundler yields a great deal of flexibility and consisency. This affords you the ‘best of both worlds&#8217;, system level isolation with the ability to install gems from git repositories, and in application gem loading based on application environment.</p>
<p>For more information RVM&#8217;s gemsets, check out the <a href="http://rvm.beginrescueend.com/gemsets/">Gemset&#8217;s section</a> on the rvm site. For more information on Bundler, check out <a href="http://gembundler.com/">Bundler&#8217;s documentation</a>.</p>
<h3 id="gemset_hierarchy">Gemset Hierarchy</h3>
<p>The second feature I use often is the global gemset.  Each ruby interpreter installation comes with two gemsets out of the box &#8211; the default (blank) gemset (e.g. <code>ree-1.8.7-2010.02</code>) and the global gemset (e.g. <code>ree-1.8.7-2010.02@global</code>).  When you use any gemset, rvm not only sets the gem home to a uniq directory for the given gemset (ensuring gems are installed in the correct place) but it also sets <code>GEM_PATH</code>.</p>
<p>Much like <code>PATH</code>, <code>GEM_PATH</code> is a colon separated list of directories that rubygems uses to look up gems when requiring them. By installing a gem to the global gemset for any ruby, e.g. <code>ree-1.8.7-2010.02@global</code>, it will automatically be made available (including it&#8217;s binaries) inside both the default gemset and any user-defined gemsets. E.g.,</p>
<ul>
<li><code>ree-1.8.7-2010.02</code></li>
<li><code>ree-1.8.7-2010.02@bighelpmob</code></li>
<li><code>ree-1.8.7-2010.02@tedxperth</code></li>
</ul>
<p>Will all have access to gems installed in <code>ree-1.8.7-2010.02@global</code>.</p>
<p>This comes in super handy for things like <code>awesome_print</code>, <code>wirble</code>, <code>bundler</code>, <code>git-up</code>, <code>homesick</code> &#8211; Namely, gems you want available in every environment.</p>
<p>Unfortunately, bundler currently does not support multiple items in <code>BUNDLE_PATH</code>. We have hope it will be added in the future but for now gems you want shared between apps using bundler, you&#8217;ll get some duplication.</p>
<h3 id="default_global_gemset_contents">Default Global Gemset Contents</h3>
<p>As an added bonus along side the global gemsets, rvm provides a way to declare a file which tells it what gems to install initially. To do this, it uses a ruby string-based directory hierarchy (see the link below) to look for a global.gems file that rvm then imports &#8211; For example, my <code>~/.rvm/gemsets/global.gems</code> (that is imported into the global gemset of all ruby interpreter installs) contains the following simple list:</p>
<pre><code>rake
rdoc
awesome_print
bundler
git-up
ghost
homesick
wirble</code></pre>
<p>For more information on this feature, be sure to read the <a href="http://rvm.beginrescueend.com/gemsets/initial/">Automatic Gemset Initialization</a> page on the RVM site.</p>
<h2 id="set_operations">Set operations</h2>
<p>If you are writing gems, one of the most important things you can do as a Ruby developer  these days is to ensure they work on all of the major implementations. At the moment, for most gem developers you should generally be testing your code against:</p>
<ul>
<li>REE / 1.8.7</li>
<li>1.9.2</li>
<li>Rubinius</li>
<li>Jruby</li>
</ul>
<p>And optionally, MagLev and MacRuby. RVM provides tools making it simple to run code and commands against multiple rubies. This includes but is not limited to running Rake tasks and tests / specs. The idea being to make it as frictionless as possible to test your gem against all of the above interpreters. As an example, you can run:</p>
<pre><code>rvm rake test</code></pre>
<p>Which will run <code>rake test</code> against all of your installed ruby interpreters (using default gemset for each). You may need to do some manual setup (e.g. installing test gem dependencies) but rvm tries to make it all as simple as possible and more importantly, heavily integrated into your normal work flow whilst staying out of the way.</p>
<p>Along side rake, rvm also provides wrappers for many common binaries (e.g. ruby, spec and the like) plus the <code>--json</code> and <code>--yaml</code> flags which make it simple to get a summarised view of the program results. Using <code>rvm exec</code>, you can even perform set operations against any arbitrary command.</p>
<p>There is a whole lot more set operations can do and I suggest anyone using or considering using rvm read the <a href="http://rvm.beginrescueend.com/set/">set&#8217;s section</a> on the rvm site. Go forth and have sets!</p>
<h2 id="tools_for_easing_dependency_related_pains">Tools for easing dependency-related pains</h2>
<p>One of the most commonly encountered problems (since for most people, the ruby interpreter you&#8217;d normally use is distributed as a binary install) are related to external dependencies &#8211; Namely, things like readline, iconv and openssl.</p>
<p>In an attempt to make life easier (and in particular, work around common problems like a neutered libedit instead of readline on OSX), rvm provides the <code>rvm package</code> set of commands that make it easy to install sandboxed versions of these in the ~/.rvm/usr directory.</p>
<p>As an example, to work around the libedit vs. readline issue on OSX, you can build your ruby against readline 6.0 by running:</p>
<pre><code>rvm package install readline
rvm install &lt;ruby&gt; --with-readline-dir=$HOME/.rvm/usr</code></pre>
<p>And, as an added bonus, to automatically patch older versions of ree and 1.8.7 to respond to Control-C immediately (for example, in irb) instead of when you press enter, you can replace the <code>rvm install</code> command above with:</p>
<pre><code>rvm install &lt;ruby&gt; --with-readline-dir=$HOME/.rvm/usr --patch readline-fix</code></pre>
<h2 id="simple_ruby_upgrades">Simple Ruby Upgrades</h2>
<p>Say, for example, a new version of 1.9.2 comes out in the next few weeks and you want to automatically update your rubies to match it correctly. As of approximately rvm 1.0.0,  we added an <code>rvm upgrade</code> command that automatically handles doing the following:</p>
<ul>
<li>Installing the new ruby</li>
<li>Moving across gemsets</li>
<li>Updating wrapper scripts and aliases</li>
</ul>
<p>The only thing you typically have to update are references in your .rvmrc&#8217;s and your passenger configuration. But, with a little forethought (e.g. creating an alias using <code>rvm alias create</code>), it&#8217;s entirely possible to make it so the entire upgrade is automatic.</p>
<p>I have personally used this feature to move from the 1.9.2 release candidate to the final patchlevel 0 release &#8211; I used <code>rvm upgrade</code> to simplify the process of updating each time it was bumped.</p>
<p>This is currently undocumented on the rvm site but documentation will be added &#8211; for the moment, in your rvm install, run <code>rvm help upgrade</code> and/or <code>rvm upgrade help</code>.</p>
<h2 id="location_matters">Location Matters</h2>
<p>One of the underlying decisions related to rvm&#8217;s architecture is where it installs your rubies &#8211; In most cases, rvm will install your rubies into <code>~/.rvm/rubies</code> and gems into <code>~/.rvm/gems</code>. This means that you should almost never have to use sudo for commands (there are a few exceptions, most notably passenger which relies on root permission in order to bind to port 80).</p>
<p>This approach is simple on the scale of things but also brings a lot of freedom &#8211; for one, it means you are free to experiment with a Ruby / RVM setup, wiping it away when you&#8217;re done with a simple <code>rm -rf ~/.rvm &amp;&amp; mv .rvm-original .rvm</code>.</p>
<h2 id="rvmrc_files">.rvmrc files</h2>
<p>All of this is fine and dandy, but when you still have to manually switch ruby interpreters and rubies each time you do something, it can become mildly annoying rather fast. For this exact reason RVM offers project-specific .rvmrc files &#8211; If you haven&#8217;t encountered them before, project .rvmrc&#8217;s are files that are automatically sourced into the current shell when you change (cd) into a directory containing one. These files can contain anything that is valid shell script (and to prevent RVM automatically running code you don&#8217;t want, it defaults to asking you to trust it the first time it is run) making things like project bootstrapping and configuration simple and mostly automatic after a quick setup in the project root directory:</p>
<pre><code>rvm --rvmrc --create &lt;ruby&gt;@&lt;gemset&gt;</code></pre>
<p>In my own projects, I use these to automatically install the Ruby if not present, create and use a project-specific gemset and then do the minimum possible required to bootstrap the new environment &#8211; in most cases, this is simply a matter of installing a few gems (e.g. for me, I install bundler via <code>rvm gemset import</code>).</p>
<p>In some cases, I even automatically run <code>bundle install</code> (with 1.0, if you have the gems already installed, this is very fast) hence the first time I cd into a project it essentially bootstraps the entire environment for me automatically.</p>
<p>Ultimately, this approach means that the Ruby interpreter and gemset switching are completely transparent to me &#8211; No matter which project I&#8217;m using, ruby and irb are available and point to the correct executable for the current project I am in. When integrated with some code I wrote for ruby summer of code, it&#8217;s even possible to have passenger automatically use this .rvmrc file to automatically change your application&#8217;s gemset at run time.</p>
<p>For more information on .rvmrc files, check out the <a href="http://rvm.beginrescueend.com/workflow/rvmrc/">rvmrc page</a> and the <a href="http://rvm.beginrescueend.com/workflow/projects/">Project Workflow page</a> on the rvm site. See <a href="http://rvm.beginrescueend.com/integration/passenger/">RVM&#8217;s passenger integration page</a> page for more details on gemsets with passenger.</p>
<h2 id="conclusion">Conclusion</h2>
<p>I hope that you have found at least one new or useful thing about RVM.  RVM has been invaluable to me as a developer on multiple open source projects over the last several months. It makes it simple for me to do things that are otherwise harder or less flexible and generally stays out of my way.</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2010/09/rvm-more-than-ruby-1-9-and-rails-3/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2010/09/rvm-more-than-ruby-1-9-and-rails-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Specjour with Custom Bundler and Database Setup</title>
		<link>http://blog.thefrontiergroup.com.au/2010/06/specjour-with-custom-bundler-and-database-setup/</link>
		<comments>http://blog.thefrontiergroup.com.au/2010/06/specjour-with-custom-bundler-and-database-setup/#comments</comments>
		<pubDate>Fri, 25 Jun 2010 05:51:27 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Inside TFG]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Specjour]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/?p=811</guid>
		<description><![CDATA[We have a test suite here that now is rapidly approaching 2 hours using a single core. Let me just repeat that. A developer realistically would have to leave their machine testing overnight to see if the suite is working. That&#8217;s really not good enough. Specjour has been a bit of a turn-key miracle worker [...]]]></description>
			<content:encoded><![CDATA[<p>We have a test suite here that now is rapidly approaching 2 hours using a single core. Let me just repeat that. A developer realistically would have to leave their machine testing overnight to see if the suite is working. That&#8217;s really not good enough.</p>
<p><a href="http://github.com/sandro/specjour">Specjour</a> has been a bit of a turn-key miracle worker with our RSpec suite, however lately we&#8217;ve started to require some custom database setup that we do in a seeds.rb file as well as some custom bundler install parameters as most of our devs don&#8217;t have MySQL installed. Both of our needs were being nicely stomped on by Specjour so I thought it was time to look elsewhere.</p>
<p>I took a trip down <a href="http://wiki.github.com/ngauthier/hydra/">Hydra</a> lane and while getting to the point of having a working, local, dual runner system was a piece of cake, getting something working remotely via SSH took me hours of pain. Debugging the remote SSH workers was a nightmare and I spent a couple of hours running through code before deciding it was probably better to update our existing solution rather than tooling up a brand new one.</p>
<p>Back to the Specjour code. Specjour includes a rails directory inside which is an init.rb which Rails will run at initialisation (it&#8217;s part of what Rails does) but the Specjour initialiser will always just run the default database setup task no matter what initialiser you&#8217;ve got setup. We had a specjour initialiser that runs if ENV['PREPARE_DB'] was populated, which it is by Specjour, the problem was that the Specjour initialiser ran in the Rails <code>after_initialization</code> hook and therefore stomped all over our database setup.</p>
<p>The first step was just to have our initialiser write to another ENV element and then to have the Specjour <code>after_initialize</code> handler respect this. This isn&#8217;t too hard to implement as the <code>after_initialize</code> handler is just a block that is attached and so inside of this block you just need to check that ENV element. In my case I created a new ENV['DB_PREPPED'] element when my database setup had completed and then when the <code>after_initialize</code> block runs it checks for ENV['DB_PREPPED'] and will do nothing if that&#8217;s been set to true.</p>
<p>Easy. I now had Specjour respecting our database setup task.</p>
<p>The next step was to try and test this outside of a Rails application, not only that but to test the operation of a block (anonymous function?). To do this I setup a stub on a mock Rails class and let it capture the <code>after_initialize</code> block and then I ran a number of specs against this block.</p>
<pre>module Specjour
  module DbScrub
  end
end

DO_NOT_REQUIRE = true

describe "Rails Initialiser" do
  before :all do
    ENV['PREPARE_DB'] = "true"

    stub(Specjour::DbScrub).scrub

    class Rails
      class &lt;&lt; self; attr_accessor :configuration; end
      class &lt;&lt; self; attr_accessor :test_block; end
    end

    config = Object.new
    stub(config).after_initialize { |args|
      object = Object.new
      Rails.test_block = args
      object
    }
    Rails.configuration = config

    require 'rails/init'
  end

... tests ...</pre>
<p>This code essentially mocks up Rails.configuration and then stubs the <code>after_initialize</code> method. This stub then places the block that <code>after_initialize</code> yields to into Rails.test_block. When I <code>require 'rails/init'</code> it sequentially processes the file (as with all Ruby) and the stub will capture the block. After this is a bunch of tests I run an whether the <code>Specjour::DbScrub.scrub</code> method is called or not, so it&#8217;s nothing special.</p>
<p>I felt like at this stage I had fairly well tested the main aspects of the database setup.</p>
<p>The next issue was with how bundler was being handled. We have a situation where we would like to install sometimes without some gems. Some of the gems we use and have written use applications we&#8217;d rather not maintain in development and get tested in our staging and production environments. We generally will run a bundle install in development without the production or metrics groups so I wanted to have the ability to pass through a custom bundler command. That&#8217;s pretty easy now with my gem. Inside .specjour/bundler.yml there is a command property. I think this is more complex than what&#8217;s required, but I can foresee us needing a number of custom rake tasks and shell scripts so this bundler.yml should have probably started life as a settings/commands/something_generic.yml</p>
<p>To test this part of my changes was pretty simple. I basically just stubbed the system calls to bundler to give certain return values and checked to make sure the correct program flow happened.</p>
<pre>describe ".bundle_install" do
    let :manager do
      stub.instance_of(Specjour::Manager).project_path { "/tmp" }

      stub(Dir).chdir(anything) { |args|
        args.last.call # This yields to the block for Dir.chdir()
      }

      manager = Specjour::Manager.new
      stub(manager).project_path { "blah" }
      mock(manager).system('bundle lock')

      manager
    end

    it "should perform a bundle lock" do
      stub(manager).system('bundle check &gt; /dev/null') { true }

      manager.bundle_install
    end

    it "should check if there are gems required" do
      mock(manager).system('bundle check &gt; /dev/null') { true }

      manager.bundle_install
    end

    context "when gems are required" do
      before :each do
        # Not a before :all as it needs to hook into the let hook above

        stub(manager).system('bundle check &gt; /dev/null') { false }
      end

      context "and there is a bundler YAML file" do
        before :each do
          config_file = ".specjour/bundler.yml"

          mock(File).exists?(config_file) { true }
          mock(File).read(config_file) { "" }
          mock(YAML).load(anything) {
            { 'command' =&gt; "do it" }
          }
        end

        it "should get the bundle command from the YAML file" do
          mock(manager).system('do it &gt; /dev/null')
          manager.bundle_install
        end
      end

      context "and there is no bundler YAML file" do
        before :each do
          mock(File).exists?(".specjour/bundler.yml") { false }
        end

        it "should perform a bundle install" do
          mock(manager).system('bundle install &gt; /dev/null')
          manager.bundle_install
        end
      end
    end
  end</pre>
<p>You can see that I stubbed our the <code>Dir.chdir</code> block to just yield directly to the call, otherwise it&#8217;ll throw an exception. Then I stubbed and mocked out the <code>Kernel.system</code> calls as necessary. Kernel methods are generally included into Ruby objects so you don&#8217;t stub Kernel, you stub the object that has the Kernel methods. Most of the testing is pretty basic, but I&#8217;d be keen to hear if I&#8217;m doing anything incorrectly!</p>
<p>This was my first major venture into adding functionality to a public project and it was good fun. I think it made me do a little better work than I might normally, it&#8217;s a great motivation to potentially have peers look at how you do things.</p>
<p>After bundling it all up and testing it here with over a dozen developers and even more machines I&#8217;m pretty happy with how it functions. I&#8217;ve made a pull request back to the original gem creator and hopefully he&#8217;ll like what I&#8217;ve done. In the meantime if you want to check it out then my Specjour is available on <a href="http://github.com/ozzyaaron/specjour">Git Hub</a>.</p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2010/06/specjour-with-custom-bundler-and-database-setup/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2010/06/specjour-with-custom-bundler-and-database-setup/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Named Scopes with Joins and Default Block Arguments</title>
		<link>http://blog.thefrontiergroup.com.au/2010/05/named-scopes-with-joins-and-default-block-arguments/</link>
		<comments>http://blog.thefrontiergroup.com.au/2010/05/named-scopes-with-joins-and-default-block-arguments/#comments</comments>
		<pubDate>Tue, 04 May 2010 06:19:56 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Named Scopes]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/?p=723</guid>
		<description><![CDATA[Today I was fiddling with some code to get particular types of payments that are due on particular days and I ran across a couple of things I don&#8217;t want to solve again. Firstly, the problem of being able to have default arguments to a block in ruby. It&#8217;s solved nicely in Ruby 1.9 but [...]]]></description>
			<content:encoded><![CDATA[<p>Today I was fiddling with some code to get particular types of payments that are due on particular days and I ran across a couple of things I don&#8217;t want to solve again.</p>
<p>Firstly, the problem of being able to have default arguments to a block in ruby. It&#8217;s solved nicely in Ruby 1.9 but we&#8217;re using 1.8.x on our boxes at the moment. The work around is incredibly simple though and goes something like this :</p>
<p><code class="ruby"><br />
lambda { |*args|<br />
date = (args[0] || Date.today)<br />
.. remaining code ..<br />
}<br />
</code></p>
<p>That&#8217;s all there is to it really. You could go the whole hog with hashed attributes and so on but I think it starts to get a bit smelly if your anonymous functions are taking more than one argument.</p>
<p>The other issue I had was whether a named scope can include a join, and it can.</p>
<p><code class="ruby"><br />
named_scope :credit_card, { :joins =&gt; :subscription, :conditions =&gt; "subscriptions.method = 'credit_card'" }<br />
</code></p>
<p>You can hash it all out if you want to, though if it&#8217;s all about readability I find the above to be more suitable. However this will also work :</p>
<p><code class="ruby"><br />
... :conditions { :payment_plans =&gt; { :payment_method =&gt; "credit_card" } }<br />
</code></p>
<p>The coolest thing about all of this though (and I feel I&#8217;m very late to the party here) is that I now get to do things like :</p>
<p><code class="ruby"><br />
Payment.credit_card.due_on(Date.today)<br />
# or<br />
Payment.credit_card.due_on<br />
# or<br />
Payment.due_on(Date.today + 1.month)<br />
</code></p>
<p>In the above I had just used the default argument to the due_on named scope to be today&#8217;s date.</p>
<p>I mean, I&#8217;d seen a bunch of tutorials on named scopes and how they worked but hadn&#8217;t found a use case in my work. I think it&#8217;s finally twigged for me though and will be making use of them a bit more in the future. </p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2010/05/named-scopes-with-joins-and-default-block-arguments/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2010/05/named-scopes-with-joins-and-default-block-arguments/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running RSpec in Distributed and Parallel using Specjour</title>
		<link>http://blog.thefrontiergroup.com.au/2010/04/running-rspec-in-distributed-and-parallel-using-specjour/</link>
		<comments>http://blog.thefrontiergroup.com.au/2010/04/running-rspec-in-distributed-and-parallel-using-specjour/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 09:27:20 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Inside TFG]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[rspec]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Specjour]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/?p=715</guid>
		<description><![CDATA[Just to cut to the chase, Specjour will easily allow you to run your tests in parallel on your local machine, or in a distributed way on your network. It cut our test suite from over 11 minutes to under 2.5 minutes. We went from one Macbook Pro to a Macbook Pro plus an iMac. [...]]]></description>
			<content:encoded><![CDATA[<p>Just to cut to the chase, Specjour will easily allow you to run your tests in parallel on your local machine, or in a distributed way on your network. It cut our test suite from over 11 minutes to under 2.5 minutes. We went from one Macbook Pro to a Macbook Pro plus an iMac. Specjour is gooood, but continuing &#8230;</p>
<p>We were running into issues with our testing suite running past 15 minutes to run. It caused a number of issues, firstly it disuaded people from running the suite for small changes they thought would be okay, secondly people tended to slow down or not work at all when the suite was running. Given we were building tests into an existing code base and coverage was running generally under 30% this was already <strong>really</strong> worrying. </p>
<p>We&#8217;ve been concentrating primarily on functional testing with RSpec so I went looking for solutions for trying to parallelise RSpec specifically. I tried parallel-tests but I couldn&#8217;t get it to work. Then I heard about Specjour on a Hashrocket video so I decided to give that a try. It worked pretty well out of the box, I just had to plug up a wayward plugin, update the rsync config file for the project and change one of the files in the gem to call a different rake task. </p>
<p><a href="http://github.com/sandro/specjour">Specjour</a> essentially uses Bonjour to find workers on the network and dispatch tests to them and it uses rsync to synchronise the project you&#8217;re testing to the remote server. Once the sync has happened then runs the rake task to setup the databases, loads the environment and starts accepting the tests that are dispatched to it. </p>
<p>The instructions will work for the majority of people, I only had some hiccups due to our project. Essentially I gem installed specjour which gave me a specjour executable which I ran to create a dRb server that communicates via Bonjour. Then in my project I added specjour to my Gemfile (all managed via Bundler!) and ran <code>rake specjour</code>. </p>
<p>For me, I ended up having a few hundred failing tests, all to do with the Ruby version of a stack overflow (stack level too deep). It turned out it was caused by a plugin calling alias method chain twice so that the original method ended up being aliased to the replacement method and so there was an infinite loop. Once I applied a fix then we were only down to a few failing tests to do with seed data. </p>
<p>I changed the db_scrub.rb file to perform a different rake task for us as we do require some seed data and then we were on our way. </p>
<p>Previously on my Macbook Pro the suite ran in just over 11 minutes, after turning on a four core iMac and my Macbook Pro I had six workers ready to go and it took about 2.5 minutes to run our tests. I&#8217;d really like to crank up the other few iMacs and the 10 or so Macbooks and see what happens then. </p>
<p>I think the only changes we&#8217;ll require is to be able to specify which task is run to create the databases, other than that it works perfectly. </p>
<p>In closing I&#8217;d say I tried a number of distributed and parallel methods for running our tests and I like Specjour the best. Apparently it will run Cucumber tests as well, I&#8217;m hoping to move on to that soon enough. </p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2010/04/running-rspec-in-distributed-and-parallel-using-specjour/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2010/04/running-rspec-in-distributed-and-parallel-using-specjour/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Setting Up an iMac Pairing Station for Rails Development</title>
		<link>http://blog.thefrontiergroup.com.au/2010/04/setting-up-an-imac-pairing-station-for-rails-development/</link>
		<comments>http://blog.thefrontiergroup.com.au/2010/04/setting-up-an-imac-pairing-station-for-rails-development/#comments</comments>
		<pubDate>Thu, 22 Apr 2010 09:08:33 +0000</pubDate>
		<dc:creator>Aaron</dc:creator>
				<category><![CDATA[Inside TFG]]></category>
		<category><![CDATA[Apple]]></category>
		<category><![CDATA[iMac]]></category>
		<category><![CDATA[Rails]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://thefrontiergroup.com.au/blog/?p=599</guid>
		<description><![CDATA[I used this post today as a guide on how to get another iMac up and running so I thought it was probably a good point to chuck this up here, if only for our own reference. We are starting with a 27&#8243; iMac and a base Snow Leopard install. The first step was to [...]]]></description>
			<content:encoded><![CDATA[<p>I used this post today as a guide on how to get another iMac up and running so I thought it was probably a good point to chuck this up here, if only for our own reference. </p>
<p>We are starting with a 27&#8243; iMac and a base Snow Leopard install. </p>
<p>The first step was to install Xcode from the Snow Leopard disc, you&#8217;ll find it in the Optional Installs part of the disc. </p>
<p>Ruby and RubyGems comes with Snow Leopard by default so we&#8217;ll use them. You&#8217;ll likely need to update the RubyGems system :</p>
<pre class="console">
    sudo gem update --system
</pre>
<p>Now we can install Rails :</p>
<pre>
  sudo gem install rails
</pre>
<p>This will install the latest stable version of Rails. We need a specific version for some of our applications (until we&#8217;ve tested it under the newer version) and you can do this by adding the -v switch : </p>
<pre>
  sudo gem install rails -v=2.3.4
</pre>
<p>After this we can switch on Apache and install passenger, the module that runs Rails on Apache. So turn on Web Sharing in the Sharing panel of your System Preferences. </p>
<pre>
  sudo gem install passenger
  sudo passenger-install-apache2-module
</pre>
<p>This will compile the Apache module and give you some text to paste into your apache conf file to load it. I keep this in a separate config file in /etc/apache2/other/passenger.conf. It should look something like : </p>
<pre>
  LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-2.2.8/ext/apache2/mod_passenger.so
  PassengerRoot /Library/Ruby/Gems/1.8/gems/passenger-2.2.8
  PassengerRuby /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby
</pre>
<p>Next download the Passenger Preference Pane so you can control your Rails sites from the OS X Preferences area. You can get it from <a href="http://www.fngtps.com/passenger-preference-pane">http://www.fngtps.com/passenger-preference-pane</a>. You should now be able to run Rails websites on your local machine very easily.</p>
<p>We use Git for our source control and Git X is the best GUI for this on OS X at the moment. You can download Git for OS X from <a href="http://code.google.com/p/git-osx-installer/">http://code.google.com/p/git-osx-installer/</a> and you can get GitX from <a href="http://gitx.frim.nl/">http://gitx.frim.nl/</a>.</p>
<p>I like to use a Pomodoro timer when pairing and the one I like the best for OS X is just called Pomodoro Desktop. It will keep people focussed and also can serve to keep the control swapping in a fairly regular way. You can find out about how Pomodoro works <a href="http://www.pomodorotechnique.com/">here</a>.</p>
<p>We use Github for our repository and exchange is done via SSH, so you&#8217;ll need to generate an SSH key and put that into your Github account. </p>
<pre>
  ssh-keygen
  cat ~/.ssh/id_rsa.pub
</pre>
<p>Copy the output and put that into your public SSH keys in Git Hub. </p>
<p>When pairing with Git the ability to have both parties responsible for the work they&#8217;re doing is appreciated sometimes. Especially twelve months from now when you can&#8217;t remember why you did something. Not that you don&#8217;t comment your code, or always write beautifully understandable code. There is a nice gem called <a href="http://github.com/therubymug/hitch">hitch</a>. It comes out of Hashrocket and handles the &#8216;hitching&#8217; and &#8216;unhitching&#8217; of partners on a machine. We have a pairing station so generally we just want to change the pair that&#8217;s in operation, so it works well. You&#8217;ll need to be inside a git repository to do the initial setup. I cloned one of our projects and then you issue : </p>
<pre>
  hitch -m
</pre>
<p>Which will prompt you for your main email address, this is the email address that all devs in your team receive, or a group email of some sort. </p>
<p>Now to hitch two devs you&#8217;d do : </p>
<pre>
  hitch dev1 dev2
</pre>
<p>This will prompt you for names of the dev1 and dev2 users so that they&#8217;ll be displayed in your commit. It&#8217;ll also associate your commits to the email address devs+dev1+dev2@company.com if you setup devs@company.com as the email address when you issued the hitch -m command. If you setup gravatars for all your devs+user1+user2@company.com email addresses then you&#8217;ll get a nice picture in Github too. </p>
<p>I think that&#8217;s about it really. We obviously just install gems as required and make customisations on a per developer need. We generally use Textmate for editing so this means installing a theme (we use the Railscast theme) and the relevant bundles for Rspec, Haml and Sass. </p>
<script src="http://feeds.feedburner.com/~s/TranscendingFrontiers?i=http://blog.thefrontiergroup.com.au/2010/04/setting-up-an-imac-pairing-station-for-rails-development/" type="text/javascript" charset="utf-8"></script>]]></content:encoded>
			<wfw:commentRss>http://blog.thefrontiergroup.com.au/2010/04/setting-up-an-imac-pairing-station-for-rails-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

