<?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>Carbon Five Community &#187; Ruby (on Rails)</title>
	<atom:link href="http://blog.carbonfive.com/category/ruby-on-rails/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.carbonfive.com</link>
	<description></description>
	<lastBuildDate>Fri, 27 Aug 2010 00:24:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Deploying to Heroku from TeamCity</title>
		<link>http://blog.carbonfive.com/2010/08/ruby-on-rails/deploying-to-heroku-from-teamcity</link>
		<comments>http://blog.carbonfive.com/2010/08/ruby-on-rails/deploying-to-heroku-from-teamcity#comments</comments>
		<pubDate>Fri, 06 Aug 2010 07:09:32 +0000</pubDate>
		<dc:creator>jonah</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rapid development]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1098</guid>
		<description><![CDATA[Previously I discussed our TeamCity configuration using RVM and mentioned that we often use git to deploy projects. Today I&#8217;ll share an example of how a TeamCity build agent can trigger deployments of a application hosted on Heroku and some of the challenges I found. Add an ssh config entry for the project&#8217;s access to [...]]]></description>
			<content:encoded><![CDATA[<p>Previously I discussed our <a href="http://blog.carbonfive.com/2010/08/ruby-on-rails/using-rvm-on-teamcity-build-agents">TeamCity configuration</a> using RVM and mentioned that we often use git to deploy projects. Today I&#8217;ll share an example of how a TeamCity build agent can trigger deployments of a application hosted on <a href="http://heroku.com/">Heroku</a> and some of the challenges I found.<br />
<span id="more-1098"></span><br />
<strong>Add an ssh config entry for the project&#8217;s access to Heroku</strong></p>
<p>Much like shared github access I need to be able to specify which ssh key a particular project&#8217;s connections to heroku should use. Since I want to use client side checkouts I can&#8217;t specify a private key within TeamCity but I do know that all my compatible build agents are local so I can add a new entry to `~/.ssh/config` and define a host which will allow me to connect to Heroku with a particular key.</p>
<p><code># Heroku for #{new_project}<br />
Host heroku-#{new_project}<br />
  HostName heroku.com<br />
  User git<br />
  ForwardAgent yes<br />
  IdentityFile /home/teamcity/.ssh/teamcity_#{new_project}_rsa<br />
</code></p>
<p><strong>Add a ssh key to the Heroku account</strong><br />
Now I need to add this new key to the Heroku account for this project by installing the heroku gem in my project&#8217;s gemset and using the `heroku` command line to add the key. Heroku stores the account credentials used in `~/.heroku` and the user account running my build agents might need to connect to many different heroku accounts. I could switch my heroku credentials, upload a key, and have different projects deploy using different accounts. However since I find it useful to be able to run the heroku command line (see below) I found it preferable to have a single `teamcity` heroku account added to every project as a collaborator.<br />
<em>If you find it necessary to switch between Heroku accounts frequently this tool from Aeonscope might be useful:</em> <a href="http://www.aeonscope.net/2010/02/22/managing-multiple-heroku-accounts/">managing multiple heroku accounts</a></p>
<p>Now I can add a key to the current project&#8217;s Heroku account.<br />
<code>heroku keys:add ~/.ssh/teamcity_#{new_project}_rsa</code></p>
<p><strong>Deploying to Heroku</strong><br />
Now I can add a simple TeamCity build configuration which pushes code to Heroku once a particular revision passes the tests.</p>
<table>
<tbody>
<tr>
<td>Command executable</td>
<td>git</td>
</tr>
<tr>
<td>Command parameters</td>
<td>push git@heroku-#{new_project}:#{new heroku project&#8217;s name}.git master</td>
</tr>
</tbody>
</table>
<p><div id="attachment_1132" class="wp-caption alignnone" style="width: 585px"><a href="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_heroku_build_runner.png"><img src="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_heroku_build_runner.png" alt="" title="tc_heroku_build_runner" width="575" height="319" class="size-full wp-image-1132" /></a><p class="wp-caption-text">A project's deployment build configuration</p></div><br />
<strong>Deploying and running database migrations</strong><br />
I don&#8217;t want my app trying to respond to requests while waiting for a database migration to finish so now it becomes necessary to put the app in maintenance mode before deploying and migrating.</p>
<table>
<tbody>
<tr>
<td>Command executable</td>
<td>sh</td>
</tr>
<tr>
<td>Command parameters</td>
<td>-c heroku maintenance:on &#8211;app #{new_project} &#038;&#038; sleep 60 &#038;&#038; git push git@heroku.com:#{new_project}.git master &#038;&#038; heroku rake db:migrate &#8211;app #{new_project} &#038;&#038; heroku maintenance:off &#8211;app #{new_project}</td>
</tr>
</tbody>
</table>
<p>I found that I need to add a delay between turning on maintenance mode for the app and pushing to heroku. Attempting to push immediately fails with the error `Heroku push rejected, your slug is currently being compiled. Please try again later.` Even with a significant delay I still see this error occasionally and have to rerun the deploy build but at this point I don&#8217;t know of a way to make sure heroku can handle a new revision before attempting to push changes.</p>
<p>Now I can use TeamCity to automatically deploy changes to Heroku as soon as my project&#8217;s tests pass.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/08/ruby-on-rails/deploying-to-heroku-from-teamcity/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using RVM on TeamCity build agents</title>
		<link>http://blog.carbonfive.com/2010/08/ruby-on-rails/using-rvm-on-teamcity-build-agents</link>
		<comments>http://blog.carbonfive.com/2010/08/ruby-on-rails/using-rvm-on-teamcity-build-agents#comments</comments>
		<pubDate>Fri, 06 Aug 2010 04:52:16 +0000</pubDate>
		<dc:creator>jonah</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[Deployment]]></category>
		<category><![CDATA[rapid development]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=1106</guid>
		<description><![CDATA[We have been using TeamCity to manage the continuous integration, testing, and deployment of many of our recent projects. We have also been using RVM on all of our recent Rails projects to allow us to install multiple ruby versions and create isolated gemsets for each project. RVM proved to be particularly useful on our [...]]]></description>
			<content:encoded><![CDATA[<p>We have been using <a href="http://www.jetbrains.com/teamcity/">TeamCity</a> to manage the continuous integration, testing, and deployment of many of our recent projects. We have also been using <a href="http://rvm.beginrescueend.com">RVM</a> on all of our recent Rails projects to allow us to install multiple ruby versions and create isolated gemsets for each project. RVM proved to be particularly useful on our TeamCity build agents where it allows a single agent to build many projects without the fear that we will see gem or ruby version conflicts between projects or introduce dependencies on gems installed on the build server but not enumerated in the project. Here&#8217;s the configuration I have used to get our build agents to use each project&#8217;s RVM settings.<br />
<span id="more-1106"></span><br />
As much as I would like to see each project able to configure all of it&#8217;s dependencies on its environment we still have some dependencies which are not captured in the project configuration. For example we have projects which need access to a database servers or need private keys to use when deploying. As a result I have favored running as many build agents as possible as local build agents so that they share this configuration. The configuration below is therefore usually only applied once but in an environment using remote build agents it would need to be repeated or shared between every compatible remote agent&#8217;s system. Perhaps one day we&#8217;ll see each project include chef recipes to configure it&#8217;s own build environment and I would be interested to hear from anyone who has automated their CI configuration to that extent.</p>
<p><strong>1. Create a key for github access</strong><br />
   <code>> ssh-keygen -t rsa -C "#{project_name}"</code><br />
   Upload the public key to github as a deploy key for the project so that the build agent can pull from the github repository.</p>
<p><strong>2. Setup rvm and a gemset for the project</strong><br />
<code>> rvm install ruby-#{version}-r#{patch level}<br />
> rvm use ruby-#{version}-r#{patch level}<br />
> rvm gemset create #{project name}<br />
> rvm gemset use #{project name}<br />
> gem install bundler</code></p>
<p><em>This could probably all be automated as part of the project&#8217;s .rvmrc file.</em></p>
<p><strong>3. Setup a ssh config for the project</strong><br />
The keys used by many of the services we interact with are unique and tied to an account so we need to have TeamCity use different ssh keys when connecting to projects under different accounts. Add a new entry to ~/.ssh/config to alias a host to use a specific ssh key</p>
<p><code># GitHub for #{new_project}<br />
Host github-#{new_project}<br />
    HostName github.com<br />
    User git<br />
    ForwardAgent yes<br />
    IdentityFile /home/teamcity/.ssh/teamcity_#{new_project}_rsa<br />
</code></p>
<p>Connections to `github-#{new_project}` will now default to use `teamcity_#{new_project}_rsa` rather than the default `id_rsa`. By specifying the key in the ssh config file we&#8217;re able to use client side checkouts which will be useful when deploying using git. For projects able to use server side checkouts we can specify a private key to use in TeamCity&#8217;s VCS settings. </p>
<p><strong>4. Create a new TeamCity project</strong><br />
On projects with multiple build steps using the same build runner we could create a template to avoid repeating these settings in each build phase. Unfortunately TeamCity 5.1 templates do not support running multiple types of build runners so projects with both command line (`bundle install`) and rake runners (`rake spec`) require some repetition.</p>
<table>
<thead>
<tr>
<th>Setting the VCS root:</th>
</tr>
</thead>
<tbody>
<tr>
<td>Type of VCS</td>
<td>Git(JetBrains)</td>
</tr>
<tr>
<td>Fetch URL</td>
<td>git@github-#{project name}:#{account name}/#{project name}.git</td>
</tr>
<tr>
<td>Authentication method</td>
<td>default private key</td>
</tr>
</tbody>
</table>
<table>
<thead>
<tr>
<th>Version Control Settings:</th>
</thead>
<tbody>
<tr>
<td>VCS Checkout Mode</td>
<td>Automatically on client</td>
</tr>
</tbody>
</table>
<p>Client checkouts have a full git repository while a server side checkout performs a git pull and then copies the resulting files but not the full git work-tree to the build agents leaving the agents unable to easily run git commands. A client side checkout is therefore preferable when using `git push` to deploy a project.</p>
<table>
<thead>
<tr>
<th>Command line tasks (bundle install):</th>
</tr>
</thead>
<tbody>
<tr>
<td>Runner</td>
<td>command line</td>
</tr>
<tr>
<td>Executable</td>
<td>/home/teamcity/.rvm/gems/%rvm.ruby%@%rvm.gemset%/bin/bundle</td>
</tr>
<tr>
<td>Arguments</td>
<td>install</td>
</tr>
</tbody>
</table>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_cl_build_runner.png"><img src="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_cl_build_runner.png" alt="Command line build runner settings" title="tc_rvm_cl_build_runner" width="861" height="393" class="alignnone size-full wp-image-1114" /></a></p>
<table>
<thead>
<tr>
<th>Rake tasks (test):</th>
</tr>
</thead>
<tbody>
<tr>
<td>Runner</td>
<td>rake</td>
</tr>
<tr>
<td>Rake task</td>
<td>%rake.tasks%</td>
</tr>
<tr>
<td>Additional rake command line parameters</td>
<td>%rake.opts%</td>
</tr>
<tr>
<td>Ruby interpreter path</td>
<td>/home/teamcity/.rvm/rubies/%rvm.ruby%/bin/ruby</td>
</tr>
<tr>
<td>RVM Gemset Name</td>
<td>#{project name}</td>
</tr>
</tbody>
</table>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_rake_build_runner.png"><img src="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_rake_build_runner.png" alt="Rake task build runner settings" title="tc_rvm_rake_build_runner" width="852" height="548" class="alignnone size-full wp-image-1117" /></a></p>
<table>
<thead>
<tr>
<th>Configuration parameters</th>
</tr>
</thead>
<tbody>
<tr>
<td>rvm.ruby</td>
<td>ruby-#{version}-r#{patch level}</td>
</tr>
<tr>
<td>rvm.gemset</td>
<td>#{new_project}</td>
</tr>
</tbody>
</table>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_config_params.png"><img src="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_config_params.png" alt="Configuration parameters" title="tc_rvm_config_params" width="852" height="220" class="alignnone size-full wp-image-1115" /></a></p>
<p>If using a template set the `rake.tasks`, `rake.opts`, and any other configuration parameters the template uses. Each build configuration based on the template can specify its own configuration parameters but cannot override the rake task and command line parameters directly.</p>
<p>To use the project&#8217;s RVM ruby and gemset add the following environment variables with appropriate paths:</p>
<table>
<tbody>
<tr>
<td>BUNDLE_PATH 	/home/teamcity/.rvm/gems/%rvm.ruby%@%rvm.gemset%</td>
</tr>
<tr>
<td>GEM_HOME 	/home/teamcity/.rvm/gems/%rvm.ruby%@%rvm.gemset%</td>
</tr>
<tr>
<td>GEM_PATH 	/home/teamcity/.rvm/gems/%rvm.ruby%@%rvm.gemset%:/home/teamcity/.rvm/gems/%rvm.ruby%@global</td>
</tr>
<tr>
<td>PATH 	/home/teamcity/.rvm/bin:/home/teamcity/.rvm/rubies/%rvm.ruby%/bin:/home/teamcity/.rvm/gems/%rvm.ruby%@%rvm.gemset%/bin:/home/teamcity/.rvm/gems/%rvm.ruby%@global/bin:%env.PATH%</td>
</tr>
</tbody>
</table>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_environment_variables.png"><img src="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_rvm_environment_variables.png" alt="Environment variables" title="tc_rvm_environment_variables" width="854" height="355" class="alignnone size-full wp-image-1116" /></a></p>
<p>Now I can finally build a set of build configurations for a project which will all use the project&#8217;s RVM settings to isolate it from other projects on the TeamCity server.</p>
<p><a href="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_example_project.png"><img src="http://blog.carbonfive.com/wp-content/uploads/2010/08/tc_example_project.png" alt="An example set of build configurations" title="tc_example_project" width="1207" height="549" class="alignnone size-full wp-image-1122" /></a></p>
<p> JetBrains appears committed to adding RVM support to TeamCity and added the `RVM Gemset` property to rake tasks in TeamCity 5.1.3 so hopefully we&#8217;ll see additional RVM support in future releases.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/08/ruby-on-rails/using-rvm-on-teamcity-build-agents/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>How to install rails on CentOS 5.4 x64</title>
		<link>http://blog.carbonfive.com/2010/03/ruby-on-rails/how-to-install-rails-on-centos-5-4</link>
		<comments>http://blog.carbonfive.com/2010/03/ruby-on-rails/how-to-install-rails-on-centos-5-4#comments</comments>
		<pubDate>Tue, 30 Mar 2010 01:20:15 +0000</pubDate>
		<dc:creator>rob</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[centos]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=943</guid>
		<description><![CDATA[1. Download ruby source wget http://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7.tar.gz tar -zxvf ruby-1.8.7.tar.gz 2. Install dependencies sudo yum install gcc sudo yum install gcc-c++ sudo yum install zlib-devel sudo yum install openssl-devel sudo yum install readline-devel sudo yum install sqlite3-devel 3. Build ruby from source cd ruby-1.8.7 ./configure --with-openssl-dir=/usr/lib64/openssl make sudo make install 4. Download rubygems source wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz [...]]]></description>
			<content:encoded><![CDATA[<p><strong>1. Download ruby source</strong><br />
<code><br />
wget http://ftp.ruby-lang.org/pub/ruby/1.8/ruby-1.8.7.tar.gz<br />
tar -zxvf ruby-1.8.7.tar.gz<br />
</code></p>
<p><strong>2. Install dependencies</strong><br />
<code><br />
sudo yum install gcc<br />
sudo yum install gcc-c++<br />
sudo yum install zlib-devel<br />
sudo yum install openssl-devel<br />
sudo yum install readline-devel<br />
sudo yum install sqlite3-devel<br />
</code></p>
<p><strong>3. Build ruby from source</strong><br />
<code><br />
cd ruby-1.8.7<br />
./configure --with-openssl-dir=/usr/lib64/openssl<br />
make<br />
sudo make install<br />
</code></p>
<p><strong>4. Download rubygems source</strong><br />
<code><br />
wget http://rubyforge.org/frs/download.php/69365/rubygems-1.3.6.tgz<br />
tar -zxvf rubygems-1.3.6.tgz<br />
cd rubygems-1.3.6<br />
sudo ruby setup.rb<br />
</code></p>
<p><strong>5. Install gems</strong><br />
<code><br />
sudo gem install rake<br />
sudo gem install rails<br />
sudo gem install sqlite3-ruby (optional)<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/03/ruby-on-rails/how-to-install-rails-on-centos-5-4/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Test-Driven JavaScript with ScrewUnit and BlueRidge</title>
		<link>http://blog.carbonfive.com/2010/02/software-design/test-driven-javascript-with-screwunit-and-blueridge</link>
		<comments>http://blog.carbonfive.com/2010/02/software-design/test-driven-javascript-with-screwunit-and-blueridge#comments</comments>
		<pubDate>Fri, 26 Feb 2010 01:33:04 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Agile]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[Software Design]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=893</guid>
		<description><![CDATA[Jonah and I are taking our presentation about Javascript Testing on the road next Tuesday at 6:30 in Palo Alto, at the SDForum The teaser for it&#8230; Recent evolutions in JavaScript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex JavaScript, [...]]]></description>
			<content:encoded><![CDATA[<p>Jonah and I are taking our presentation about Javascript Testing on the road <a href="http://www.sdforum.org/index.cfm?fuseaction=Calendar.eventDetail&amp;eventID=13629&amp;pageId=471">next Tuesday at 6:30 in Palo Alto, at the SDForum</a></p>
<p>The teaser for it&#8230; Recent evolutions in JavaScript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex JavaScript, have confidence in the implementation, and push more of the logic from the server into the browser, reducing the load on the server&#8230;</p>
<p>Hope to see you there.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/02/software-design/test-driven-javascript-with-screwunit-and-blueridge/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Erector views &#8211; undefined method `default_url_options&#8217;</title>
		<link>http://blog.carbonfive.com/2010/01/ruby-on-rails/erector-views-undefined-method-default_url_options</link>
		<comments>http://blog.carbonfive.com/2010/01/ruby-on-rails/erector-views-undefined-method-default_url_options#comments</comments>
		<pubDate>Wed, 20 Jan 2010 19:30:18 +0000</pubDate>
		<dc:creator>james</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=800</guid>
		<description><![CDATA[I&#8217;m posting this because it took me too long to figure this out. Hope it saves someone else some trouble. If you want to use named route helpers to generate urls in your erector widgets you need to include ActionController::UrlWriter in your class, like so: class Views::Layouts::BasicPage &#60; Erector::Widgets::Page include ActionController::UrlWriter ... end]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m posting this because it took me too long to figure this out. Hope it saves someone else some trouble. If you want to use named route helpers to generate urls in your erector widgets you need to include ActionController::UrlWriter in your class, like so:</p>
<p><code><br />
class Views::Layouts::BasicPage &lt; Erector::Widgets::Page<br />
include ActionController::UrlWriter<br />
...<br />
end</code></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/01/ruby-on-rails/erector-views-undefined-method-default_url_options/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Automatically deploying to Engine Yard Cloud</title>
		<link>http://blog.carbonfive.com/2010/01/ruby-on-rails/automatically-deploying-to-engine-yard-cloud</link>
		<comments>http://blog.carbonfive.com/2010/01/ruby-on-rails/automatically-deploying-to-engine-yard-cloud#comments</comments>
		<pubDate>Thu, 07 Jan 2010 19:04:14 +0000</pubDate>
		<dc:creator>jonah</dc:creator>
				<category><![CDATA[Deployment]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[continuous integration]]></category>
		<category><![CDATA[Engine Yard Cloud]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rake]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=793</guid>
		<description><![CDATA[I&#8217;m working on a application which is deployed to Engine Yard&#8217;s Cloud infrastructure and I wanted to automatically redeploy the application whenever our tests passed on our continuous integration server. Engine Yard will eventually allow us to push a branch to our cloud environment from git (ie &#8220;git push engineyard master&#8221;) but until that is [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m working on a application which is deployed to Engine Yard&#8217;s Cloud infrastructure and I wanted to automatically redeploy the application whenever our tests passed on our continuous integration server.</p>
<p>Engine Yard will eventually allow us to push a branch to our cloud environment from git (ie &#8220;git push engineyard master&#8221;) but until that is available the best option seems to be to trigger a github post receive hook directly.</p>
<p>To that end I rewrote an existing script to trigger post receive hooks as a rake task; <a href="http://gist.github.com/271433">http://gist.github.com/271433</a><br />
<span id="more-793"></span></p>
<pre lang=ruby>
require 'rubygems'
require 'json'
begin
  require 'restclient'
rescue Exception
end

namespace :ey do

  # Based on http://gist.github.com/114954
  # Discussed at https://cloud-support.engineyard.com/discussions/questions/83-deploying-to-solo-instance-from-automated-build
  desc 'Trigger a GitHub Post Receive Hook to deploy the app'
  task :deploy do
    post_receive_hook 'preview'
  end

  desc 'Trigger a GitHub Post Receive Hook to deploy and migrate the app'
  task :deploy_and_migrate do
    post_receive_hook 'preview', true
  end

  def post_receive_hook(envname, migrate=false)
    token = `git config --get cloud.token`.chomp

    if token.empty?
      token = ENV['cloud.token']
      end

    if token.empty?
      puts <<-EOT
The cloud token is not set.
To store the token, use:
$ git config --add cloud.token SOMETOKEN
or set the cloud.token environment variable.
EOT
      exit 2
    end

    commit = `git rev-parse HEAD`.chomp
    payload = {
        "commits" => [{"id" => commit, "message"=>"[deploy #{envname}#{migrate ? ' migrate' : ''}]"}],
        "ref" => "refs/heads/master",
        }

    puts "Triggering a deploy for #{commit} on #{envname}"
    begin
      response = RestClient.post("https://cloud.engineyard.com/github/#{token}",
                                 :payload => payload.to_json)
      puts "Successfully triggered the deploy"
    rescue RestClient::RequestFailed => e
      puts "Could not deploy your changes"
      puts e.response.code
      puts e.response.body
      exit 1
    end
  end
end
</pre>
<p>In setting this up I discovered a couple of potential stumbling points:</p>
<ul>
<li>The environment must have been deployed via the EY dashboard before you will be able to trigger a deploy using the post receive hook API.</li>
<li>The branch specified in the API call (and therefore the git branch you should be working in if running that rake task) must match the branch deployed using the EY dashboard.</li>
<li>If you make an API call to deploy the &#8216;master&#8217; branch EY will attempt to deploy branch &#8216;HEAD&#8217;.</li>
<li>If the branch specified in the API call does not match the branch specified on the dashboard the API will report success but not redeploy the environment.</li>
</ul>
<p>The folks at Engine Yard are working to correct some of those issues and now I&#8217;ve got a project which automatically pushes changes to the cloud every time our tests cycle.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2010/01/ruby-on-rails/automatically-deploying-to-engine-yard-cloud/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>assert_changes and assert_no_changes in Ruby</title>
		<link>http://blog.carbonfive.com/2009/04/testing/assert_changes-and-assert_no_changes-in-ruby</link>
		<comments>http://blog.carbonfive.com/2009/04/testing/assert_changes-and-assert_no_changes-in-ruby#comments</comments>
		<pubDate>Sat, 04 Apr 2009 00:26:51 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[Agile]]></category>
		<category><![CDATA[fixtures]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=567</guid>
		<description><![CDATA[Update: This code and documentation is now available on github: http://github.com/ndp/assert_changes/tree/master The Problem On our work on gobalto.com, we spend time to have good fixture data for our tests&#8211; data that can represent all the important application states that our tests require. As a result, our tests are very dependent on the data. It&#8217;s important [...]]]></description>
			<content:encoded><![CDATA[<h3><span style="color: #000080;">Update:</span><span style="color: #000080;"> This code and documentation is now available on github:<a href="http://github.com/ndp/assert_changes/tree/master" target="_blank"> http://github.com/ndp/assert_changes/tree/master</a></span></h3>
<h2>The Problem</h2>
<p>On our work on <a href="http://www.gobalto.com">gobalto.com</a>, we spend time to have good fixture data for our tests&#8211; data that can represent all the important application states that our tests require. As a result, our tests are very dependent on the data. It&#8217;s important that someone doesn&#8217;t inadvertantly change it in subtle ways. This has led us to write not only asserts at the end of tests, but pre-conditions as well. For example,</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    ...
    <span style="color:#9900CC;">inotech</span> = companies<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:inotech</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:b</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:c</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
    post <span style="color:#ff3333; font-weight:bold;">:edit_services_dialog</span>, <span style="color:#ff3333; font-weight:bold;">:id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;inotech.<span style="color:#9900CC;">id</span>,
                                          <span style="color:#ff3333; font-weight:bold;">:service_category_id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>
    inotech.<span style="color:#9900CC;">reload</span>
&nbsp;
    assert inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert !inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:b</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    assert !inotech.<span style="color:#9900CC;">services</span>.<span style="color:#9900CC;">public</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:c</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>Although the pre-conditions were introduced to guard against accidentally changing fixture data (or just to figure out what&#8217;s going on), we don&#8217;t necessarily delete them. They provide stronger tests. And in some ways, leaving in pre-conditions make the code more readable by providing documentation of your assumptions to the readers. The code above would be hard to follow without the clarifying pre-conditions. What do we expect to change and what stays the same?</p>
<p>Unfortunately all these asserts make the tests twice as long. And there&#8217;s a subtle readability problem: there&#8217;s no relationship between the corresponding pre- and post-conditions. In the example above, you have to scan carefully to see that the three assertions are repeated, but negated (b and c only). The reader must mentally put pieces together. And it&#8217;s not DRY. Using local variables doesn&#8217;t help much.</p>
<h2>The Solution</h2>
<p>I was inspired by a nice little test helper called assert_difference. It takes a string to evaluate and a block to execute. It&#8217;s useful for checking on state changes&#8211; especially database changes&#8211; during a test:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">assert_difference<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">'Company.count'</span>, <span style="color:#006600; font-weight:bold;">-</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>
    Company.<span style="color:#9900CC;">delete_one</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>(Without this method, we rely on a count of all database records, or merely look for specific ones. The former approach leads to brittle tests, and the latter to incomplete assertions.)</p>
<p>A limitation of assert_difference is that it only deals with integers. What if it were generalized? Here goes:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    i = <span style="color:#0000FF; font-weight:bold;">true</span>
    assert_changes <span style="color:#996600;color: blue;">'i'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">do</span>   <span style="color:#008000; font-style:italic;"># read as: i changes to false</span>
      i = <span style="color:#0000FF; font-weight:bold;">false</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p><span id="more-567"></span>The string passed to assert changes is evaluated in the block context, both before and after the block is run. So this block asserts that i becomes false (and by deduction, starts out as true). It executes asserts on both ends, just like we want.</p>
<p>Of course sometimes you want to be explicit about a state change, so you can specify both the starting and ending values using an array:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    o.<span style="color:#9900CC;">answer</span> = <span style="color:#996600;color: blue;">'yes'</span>
    assert_changes <span style="color:#996600;color: blue;">'o.answer'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;color: blue;">'yes'</span>,<span style="color:#996600;color: blue;">'no'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      o.<span style="color:#9900CC;">answer</span> = <span style="color:#996600;color: blue;">'no'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>To handle the original example, you can pass multiple pre/post conditions of arbitrary complexity and they are all evaluated before and after the block is executed:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">      assert_changes <span style="color:#996600;color: blue;">'post(:a).status'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:preview</span>, <span style="color:#ff3333; font-weight:bold;">:published</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
                            <span style="color:#996600;color: blue;">'comment(:c).status'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:preview</span>, <span style="color:#ff3333; font-weight:bold;">:deleted</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        ...
      <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Finally, I added support for a :no_change symbol. Now I can re-write my original problem in a clearer form:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    assert_changes
        <span style="color:#996600;color: blue;">'inotech.services.public.include?(categories(:a))'</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF; font-weight:bold;">true</span>, <span style="color:#ff3333; font-weight:bold;">:no_change</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
            <span style="color:#996600;color: blue;">'inotech.services.public.include?(categories(:b))'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;false,
            <span style="color:#996600;color: blue;">'inotech.services.public.include?(categories(:c))'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;false <span style="color:#9966CC; font-weight:bold;">do</span>
      post <span style="color:#ff3333; font-weight:bold;">:edit_services_dialog</span>, <span style="color:#ff3333; font-weight:bold;">:id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;inotech.<span style="color:#9900CC;">id</span>, <span style="color:#ff3333; font-weight:bold;">:service_category_id</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;categories<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:a</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">id</span>
      inotech.<span style="color:#9900CC;">reload</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>For completeness, I added assert_no_changes, with slightly extended parameter possibilities:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">    i,j = <span style="color:#996600;color: blue;">'hello'</span>,<span style="color:#996600;color: blue;">'hi'</span>
    assert_no_changes <span style="color:#996600;color: blue;">'i'</span> <span style="color:#9966CC; font-weight:bold;">do</span> ...  <span style="color:#008000; font-style:italic;"># i (before) == i (after)</span>
    assert_no_changes <span style="color:#996600;color: blue;">'i'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">'hello'</span> <span style="color:#9966CC; font-weight:bold;">do</span> ... <span style="color:#008000; font-style:italic;"># i == 'hello' before and after</span>
    assert_no_changes <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;color: blue;">'i'</span>,<span style="color:#996600;color: blue;">'j'</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">do</span> ... <span style="color:#008000; font-style:italic;"># neither i or j change</span>
    assert_no_changes <span style="color:#996600;color: blue;">'i'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">'hello'</span>,<span style="color:#996600;color: blue;">'j'</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">'hi'</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#008000; font-style:italic;"># or be explicit</span></pre></div></div>

<h3><span style="color: #000080;">Update:</span><span style="color: #000080;"> This code and documentation is now available on github:<a href="http://github.com/ndp/assert_changes/tree/master" target="_blank"> http://github.com/ndp/assert_changes/tree/master</a></span></h3>
<p>Thoughts? Comments?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2009/04/testing/assert_changes-and-assert_no_changes-in-ruby/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convenient CSS and Javascript in Ruby on Rails</title>
		<link>http://blog.carbonfive.com/2009/03/javascript-ajax/convenient-css-and-javascript-in-ruby-on-rails</link>
		<comments>http://blog.carbonfive.com/2009/03/javascript-ajax/convenient-css-and-javascript-in-ruby-on-rails#comments</comments>
		<pubDate>Mon, 09 Mar 2009 00:41:11 +0000</pubDate>
		<dc:creator>andy</dc:creator>
				<category><![CDATA[CSS]]></category>
		<category><![CDATA[JavaScript / AJAX]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>
		<category><![CDATA[prototyping]]></category>
		<category><![CDATA[rapid development]]></category>
		<category><![CDATA[Software Design]]></category>

		<guid isPermaLink="false">http://blog.carbonfive.com/?p=480</guid>
		<description><![CDATA[I get tired of hunting through a hierarchy of folders and files, from the views to the public folder, to locate a certain CSS or Javascript file. It&#8217;d be convenient to have them right with the markup, but embedding these definitions within your HTML markup is a bad idea for several reasons. For our current [...]]]></description>
			<content:encoded><![CDATA[<p>I get tired of hunting through a hierarchy of folders and files, from the views to the public folder, to locate a certain CSS or Javascript file. It&#8217;d be convenient to have them right with the markup, but embedding these definitions within your HTML markup is a bad idea for several reasons. For our current project, I proposed we put everything in the view directory so they are easy to find:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">app<span style="color: #339933;">/</span>
  views<span style="color: #339933;">/</span>
    home<span style="color: #339933;">/</span>
      index.<span style="color: #006633;">html</span>.<span style="color: #006633;">rb</span>
      index.<span style="color: #006633;">css</span>
      index.<span style="color: #006633;">js</span></pre></div></div>

<p>The convention is clear: to add page-specific CSS code, just create a new file with the same name as the view, in the same folder. Easy to add, edit and remove. The alternative (using the public folder), usually leads to a parallel hierarchy and the inconvenience of that.</p>
<p>I also thought, that this being Rails and all, the files should be included automatically. It turned out to be pretty easy.<span id="more-480"></span></p>
<h2>The Implementation</h2>
<h3>Serving the Assets</h3>
<p>To serve this file, we need a route and a controller.</p>
<p>First the route:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">map.<span style="color:#9900CC;">connect</span> <span style="color:#996600;color: blue;">'/asset/:path'</span>,
    <span style="color:#ff3333; font-weight:bold;">:controller</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;color: blue;">'asset'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#996600;color: blue;">'serve_asset'</span>, <span style="color:#ff3333; font-weight:bold;">:path</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">*</span>.<span style="color:#006600; font-weight:bold;">&#40;</span>js<span style="color:#006600; font-weight:bold;">|</span>css<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span></pre></div></div>

<p>We need to be careful here, since we&#8217;re going to be serving files directly out of our view hierarchy&#8211; make sure the route only picks up the javascript and CSS files.</p>
<p>The corresponding controller:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> AssetController <span style="color:#006600; font-weight:bold;">&amp;</span>lt; ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> serve_asset
    path = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:path</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#CC0066; font-weight:bold;">format</span> = path.<span style="color:#CC0066; font-weight:bold;">sub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#006600; font-weight:bold;">*</span>.<span style="color:#006600; font-weight:bold;">&#40;</span>w<span style="color:#006600; font-weight:bold;">+</span>$<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span>, <span style="color:#996600;color: blue;">'1'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">js</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:file</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">&quot;#{RAILS_ROOT}/app/views/#{path}&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">css</span> <span style="color:#006600; font-weight:bold;">&#123;</span> render<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:file</span>=<span style="color:#006600; font-weight:bold;">&amp;</span>gt;<span style="color:#996600;color: blue;">&quot;#{RAILS_ROOT}/app/views/#{path}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</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>Now the assets mentioned above are served as /assets/index.css and /assets/index.js.</p>
<h3>Including the Assets</h3>
<p>With this convention, we added code to our layout that includes these files automatically, but only if they exist. First, the additional controller code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> AssetController <span style="color:#006600; font-weight:bold;">&amp;</span>lt; ApplicationController
  ...
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span>rel_path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#996600;color: blue;">''</span> <span style="color:#9966CC; font-weight:bold;">unless</span> AssetController.<span style="color:#9900CC;">asset_exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>rel_path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">case</span> rel_path
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#9900CC;">js</span>$<span style="color:#006600; font-weight:bold;">/</span>
        <span style="color:#996600;color: blue;">&quot;&lt;script src=&quot;</span><span style="color:#006600; font-weight:bold;">/</span>asset<span style="color:#006600; font-weight:bold;">/</span><span style="color:#008000; font-style:italic;">#{rel_path}&quot; type=&quot;text/javascript&quot;&gt;&lt;!--mce:0--&gt;&lt;/script&gt;&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">when</span> <span style="color:#006600; font-weight:bold;">/</span>.<span style="color:#9900CC;">css</span>$<span style="color:#006600; font-weight:bold;">/</span>
        <span style="color:#996600;color: blue;">&quot;
&quot;</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> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">asset_exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>rel_path<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">FileTest</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;color: blue;">&quot;/app/views/#{rel_path}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And the code needed in the (Erector) layout:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">head <span style="color:#9966CC; font-weight:bold;">do</span>
  c = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.js&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.css&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Actually, since it&#8217;s Erector, the views are Ruby classes, so there is a hierarchy. These assets may be specific to any one of these:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">c = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9966CC; font-weight:bold;">class</span>
<span style="color:#9966CC; font-weight:bold;">while</span> c != <span style="color:#CC00FF; font-weight:bold;">Object</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.js&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  rawtext AssetController.<span style="color:#9900CC;">include_asset</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;#{c.name.underscore}.css&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  c = c.<span style="color:#9900CC;">superclass</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h2>Discussion</h2>
<p>Although some people will bristle at the proliferation of files, I have used this technique repeatedly over the last five years (in Java and PHP projects). I find it leads to sound, modular development. With Ruby, it&#8217;ll be pretty straightforward to concat the assets together later on, to reduce requests, or even embed the code directly in the served HTML files, if it&#8217;s small enough. It&#8217;s also convenient to add page caching in the controller, when the time comes. Adding</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  caches_page<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:serve_asset</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>copies all these files into public/assets (as they are accessed), which conveniently takes your mongrel (or whatever) out of the picture.</p>
<p>You might imagine this keeps you from organizing and structuring your CSS and Javascript; it doesn&#8217;t do that. It lowers the barier to using a &#8220;local&#8221; scope for the CSS and Javascript. It allows you to write page-specific CSS and Javascript, which if you&#8217;re developing code quickly, is a lifesaver. We have repeatedly opened a view-specific Javascript file, seen that it no longer applies to the code, and removed it&#8211; safely. It&#8217;s easy to edit scripts when you know they only effect one page. Without this, I tend to lump things together that don&#8217;t really belong, and it becomes hard to tease them apart later.</p>
<p>Thoughts?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2009/03/javascript-ajax/convenient-css-and-javascript-in-ruby-on-rails/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Using paginating_find with has_finder</title>
		<link>http://blog.carbonfive.com/2008/02/ruby-on-rails/using-paginating_find-with-has_finder</link>
		<comments>http://blog.carbonfive.com/2008/02/ruby-on-rails/using-paginating_find-with-has_finder#comments</comments>
		<pubDate>Thu, 28 Feb 2008 02:23:04 +0000</pubDate>
		<dc:creator>alon</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog/?p=25</guid>
		<description><![CDATA[I&#8217;ve been enjoying using has_finder by Nick at Pivotal Labs and recently added pagination to the application I am providing volunteer time to for the San Francisco Bike Kitchen. I like the semantics of paginating_find over will_paginate but am not married to that choice if anyone wants to try to convince me otherwise. In any [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been enjoying using <a href="http://pivots.pivotallabs.com/users/nick/blog/articles/284-hasfinder-it-s-now-easier-than-ever-to-create-complex-re-usable-sql-queries">has_finder</a> by Nick at Pivotal Labs and recently added pagination to the application I am providing volunteer time to for the <a href="http://www.bikekitchen.org">San Francisco Bike Kitchen</a>.</p>
<p>I like the semantics of <a href="http://cardboardrocket.com/pages/paginating_find">paginating_find</a> over <a href="http://rock.errtheblog.com/will_paginate">will_paginate</a> but am not married to that choice if anyone wants to try to convince me otherwise.</p>
<p>In any case, I wanted to paginate the finders created by has_finder. I wrote a simple ActiveRecord mixin that provides a class method &#8216;acts_as_paginated and is used in your model like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Visit <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:person</span>
&nbsp;
  acts_as_paginated <span style="color:#ff3333; font-weight:bold;">:size</span><span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">10</span>
&nbsp;
  has_finder <span style="color:#ff3333; font-weight:bold;">:for_person</span>, <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>person<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:person_id</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> person<span style="color:#006600; font-weight:bold;">&#125;</span>,
    <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;color: blue;">'datetime DESC'</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  has_finder <span style="color:#ff3333; font-weight:bold;">:in_date_range</span>, <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>from,to<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;color: blue;">&quot;visits.datetime &gt;= ? and visits.datetime &lt;= ?&quot;</span>, from, to <span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Client code looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">from, to = <span style="color:#CC00FF; font-weight:bold;">Date</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>,<span style="color:#006666;">2</span>,<span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#CC00FF; font-weight:bold;">Date</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>,<span style="color:#006666;">2</span>,<span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span>
visits = Visit.<span style="color:#9900CC;">for_person</span><span style="color:#006600; font-weight:bold;">&#40;</span>@person<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">in_date_range</span><span style="color:#006600; font-weight:bold;">&#40;</span>from, to<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">paginate</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">3</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>The mixin looks like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Provides Model.paginate(options={}) to allow</span>
<span style="color:#008000; font-style:italic;"># the paginating_find plugin to be used with the has_finder plugin.</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># Usage:</span>
<span style="color:#008000; font-style:italic;">#   acts_as_paginated</span>
<span style="color:#008000; font-style:italic;">#   acts_as_paginated :page =&gt; 2, size =&gt; 10</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># Install:</span>
<span style="color:#008000; font-style:italic;">#   Save this file as lib/acts_as_paginated.rb and require 'acts_as_paginated'</span>
<span style="color:#008000; font-style:italic;">#   in environment.rb.</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#9966CC; font-weight:bold;">module</span> HasFinder
<span style="color:#9966CC; font-weight:bold;">module</span> PaginatingFind <span style="color:#008000; font-style:italic;">#:nodoc:</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">included</span><span style="color:#006600; font-weight:bold;">&#40;</span>mod<span style="color:#006600; font-weight:bold;">&#41;</span>
  mod.<span style="color:#9900CC;">extend</span><span style="color:#006600; font-weight:bold;">&#40;</span>ClassMethods<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;">module</span> ClassMethods
  <span style="color:#9966CC; font-weight:bold;">def</span> acts_as_paginated<span style="color:#006600; font-weight:bold;">&#40;</span>options=<span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1</span>, <span style="color:#ff3333; font-weight:bold;">:size</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">20</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    cattr_accessor <span style="color:#ff3333; font-weight:bold;">:paginate_defaults</span>
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">paginate_defaults</span> = options
&nbsp;
    <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">class_eval</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      extend <span style="color:#6666ff; font-weight:bold;">HasFinder::PaginatingFind::SingletonMethods</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;">module</span> SingletonMethods
  <span style="color:#9966CC; font-weight:bold;">def</span> paginate<span style="color:#006600; font-weight:bold;">&#40;</span>args=<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  options = <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">paginate_defaults</span>.<span style="color:#9900CC;">clone</span>
    options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span> = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_i</span> <span style="color:#9966CC; font-weight:bold;">if</span> args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:size</span><span style="color:#006600; font-weight:bold;">&#93;</span> = args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:size</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_i</span> <span style="color:#9966CC; font-weight:bold;">if</span> args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:size</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        find<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;">:page</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:size</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:size</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:current</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:page</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:first</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1</span> <span style="color:#006600; font-weight:bold;">&#125;</span><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>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:include</span>, <span style="color:#6666ff; font-weight:bold;">HasFinder::PaginatingFind</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>It also works to paginate associations:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#0066ff; font-weight:bold;">@person</span>.<span style="color:#9900CC;">visits</span>.<span style="color:#9900CC;">paginate</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:size</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">4</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2008/02/ruby-on-rails/using-paginating_find-with-has_finder/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>markaby_scaffold Rails Plugin</title>
		<link>http://blog.carbonfive.com/2008/02/ruby-on-rails/markaby_scaffold-rails-plugin</link>
		<comments>http://blog.carbonfive.com/2008/02/ruby-on-rails/markaby_scaffold-rails-plugin#comments</comments>
		<pubDate>Wed, 20 Feb 2008 19:32:09 +0000</pubDate>
		<dc:creator>alon</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog/?p=24</guid>
		<description><![CDATA[We&#8217;ve been enjoying using Markaby on our recent rails projects. When bootstrapping with scaffolding there&#8217;s a common recipe of turning ERB views into Markaby and then refactoring views with Markaby helper functions. One project wrote a rake task that converts ERB views to Markaby. Then Ingar created a plugin that re-implements the base Rails scaffolding [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve been enjoying using <a href="http://code.whytheluckystiff.net/markaby/">Markaby</a> on our recent rails projects. When bootstrapping with scaffolding there&#8217;s a common recipe of turning ERB views into Markaby and then refactoring views with Markaby helper functions.</p>
<p>One project wrote a rake task that converts ERB views to Markaby. Then Ingar created a plugin that re-implements the base Rails scaffolding to create Markaby views that output the same HTML as the base Rails scaffolding. I took his work one standard refactor further to introduce a MarkabyHelper with helper functions for the layout of form inputs and model views.</p>
<p><b>Usage</b></p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>script<span style="color: #000000; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> http:<span style="color: #000000; font-weight: bold;">//</span>svn.carbonfive.com<span style="color: #000000; font-weight: bold;">/</span>public<span style="color: #000000; font-weight: bold;">/</span>carbonfive<span style="color: #000000; font-weight: bold;">/</span>rails<span style="color: #000000; font-weight: bold;">/</span>plugins<span style="color: #000000; font-weight: bold;">/</span>markaby_scaffold<span style="color: #000000; font-weight: bold;">/</span>trunk<span style="color: #000000; font-weight: bold;">/</span></pre></div></div>

<p>Use it as you would regular Rails scaffolding:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">.<span style="color: #000000; font-weight: bold;">/</span>script<span style="color: #000000; font-weight: bold;">/</span>generate markaby_scaffold Post title:string body:text published:boolean</pre></div></div>

<p><b>Prerequisites</b></p>
<p>markaby_scaffold requires that you install <a href="http://redhanded.hobix.com/inspect/markabyForRails.html">Markaby as a Rails plugin</a>.</p>
<p><b>Gravy</b></p>
<p>Unfortunately, Markaby does not appear to be getting the love that it deserves. There is an issue using Markaby with Rails 2.0.2 for which <a href="http://code.whytheluckystiff.net/markaby/ticket/58">Randy has submitted a patch</a>. This plugin includes a <a href="http://en.wikipedia.org/wiki/Monkey_patch">monkey patch</a> for Markaby and Rails 2.0.2 that provides this fix so you don&#8217;t have to apply it yourself.</p>
<p>Additionally, the generated MarkabyHelper includes support for using Markaby in your helpers, provides a quick start for refactoring the scaffolding layouts and includes test cases to get you started testing your Markaby helpers.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2008/02/ruby-on-rails/markaby_scaffold-rails-plugin/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Google Talking with JRuby and Smack</title>
		<link>http://blog.carbonfive.com/2008/02/ruby-on-rails/google-talking-with-jruby-and-smack</link>
		<comments>http://blog.carbonfive.com/2008/02/ruby-on-rails/google-talking-with-jruby-and-smack#comments</comments>
		<pubDate>Sun, 03 Feb 2008 21:09:53 +0000</pubDate>
		<dc:creator>alon</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog/?p=21</guid>
		<description><![CDATA[We&#8217;ve kicked off a new project that extends well beyond standard webapp frameworks and tools including significant instant messaging integration. Portions of the project will use Ruby on Rails for web functionality. I know that the open source Jabber software from Jive Software is excellent quality and feature rich. Would JRuby be a good tool [...]]]></description>
			<content:encoded><![CDATA[<p>We&#8217;ve kicked off a new project that extends well beyond standard webapp frameworks and tools including significant instant messaging integration. Portions of the project will use <a href="http://www.rubyonrails.org">Ruby on Rails</a> for web functionality. I know that the <a href="http://www.igniterealtime.org/projects/">open source Jabber software</a> from <a href="http://www.jivesoftware.com/">Jive Software</a> is excellent quality and feature rich. Would <a href="http://jruby.codehaus.org/">JRuby</a> be a good tool for leveraging these Java libraries in a Ruby environment?</p>
<p>Here&#8217;s a toy chat client and parrot bot I wrote for the <a href="http://code.google.com/apis/talk/open_communications.html">Google Talk service</a> using JRuby and the <a href="http://www.igniterealtime.org/projects/smack/index.jsp">Java Smack API</a> from Jive&#8217;s open source portal <a href="http://www.igniterealtime.org/">ignite realtime</a>.</p>
<p><span id="more-21"></span></p>
<p><b>Dependencies</b</p>
<p>
I&#8217;m using a local install of JRuby 1.1RC1 and downloaded the Smack 3.0.4 API jars.
</p>
<pre>
lib/
smack.jar
smackx_debug.jar
smackx.jar
</pre>
<p><b>SmackHelper</b</p>
<p>I wrote a Ruby module (lib/smack_helper.rb) that provides a simple wrapper around the Smack classes:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">&nbsp;
require <span style="color: #0000ff;color: blue;">'java'</span>
require <span style="color: #0000ff;color: blue;">'smack.jar'</span>
require <span style="color: #0000ff;color: blue;">'smackx.jar'</span>
require <span style="color: #0000ff;color: blue;">'smackx-debug.jar'</span>
&nbsp;
# Helper methods <span style="color: #000000; font-weight: bold;">for</span> Smack API
module SmackHelper
&nbsp;
# Enable debug console. <span style="color: #000000; font-weight: bold;">Do</span> <span style="color: #000000; font-weight: bold;">this</span> before opening any connections
def debug
org.<span style="color: #006633;">jivesoftware</span>.<span style="color: #006633;">smack</span>.<span style="color: #006633;">XMPPConnection</span>.<span style="color: #006633;">DEBUG_ENABLED</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
end
&nbsp;
# Connect to Google Talk service and log in
def connect<span style="color: #009900;">&#40;</span>username, password, server <span style="color: #339933;">=</span> <span style="color: #0000ff;color: blue;">'talk.google.com'</span>, port <span style="color: #339933;">=</span> <span style="color: #cc66cc;">5222</span>, service <span style="color: #339933;">=</span> <span style="color: #0000ff;color: blue;">'gmail.com'</span><span style="color: #009900;">&#41;</span>
config <span style="color: #339933;">=</span> org.<span style="color: #006633;">jivesoftware</span>.<span style="color: #006633;">smack</span>.<span style="color: #006633;">ConnectionConfiguration</span>.<span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>server, port, service<span style="color: #009900;">&#41;</span>
@connection <span style="color: #339933;">=</span> org.<span style="color: #006633;">jivesoftware</span>.<span style="color: #006633;">smack</span>.<span style="color: #006633;">XMPPConnection</span>.<span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#40;</span>config<span style="color: #009900;">&#41;</span>
@connection.<span style="color: #006633;">connect</span>
@connection.<span style="color: #006633;">login</span><span style="color: #009900;">&#40;</span>username, password<span style="color: #009900;">&#41;</span>
@connection
end
&nbsp;
# Start a chat with a user on Google Talk
def chat<span style="color: #009900;">&#40;</span>username<span style="color: #009900;">&#41;</span>
puts <span style="color: #0000ff;color: blue;">&quot;Chatting with #{username}...&quot;</span>
@chat <span style="color: #339933;">=</span> @connection.<span style="color: #006633;">chat_manager</span>.<span style="color: #006633;">create_chat</span><span style="color: #009900;">&#40;</span>username, StdoutMessageListener.<span style="color: #000000; font-weight: bold;">new</span><span style="color: #009900;">&#41;</span>
end
&nbsp;
# Parrot back to the other participant in the current chat everything she says
def parrot
puts <span style="color: #0000ff;color: blue;">&quot;Parroting #{@chat.participant}.&quot;</span>
@chat.<span style="color: #006633;">add_message_listener</span> ParrotMessageListener.<span style="color: #000000; font-weight: bold;">new</span>
end
&nbsp;
# Send a message <span style="color: #000000; font-weight: bold;">for</span> the current chat
def say<span style="color: #009900;">&#40;</span>message<span style="color: #009900;">&#41;</span>
@chat.<span style="color: #006633;">send_message</span> message
end
&nbsp;
# Disconnect from the Jabber service
def disconnect
@connection.<span style="color: #006633;">disconnect</span>
@connection <span style="color: #339933;">=</span> nil
@chat <span style="color: #339933;">=</span> nil
puts <span style="color: #0000ff;color: blue;">&quot;Disconnected.&quot;</span>
end
&nbsp;
# <span style="color: #000000; font-weight: bold;">Implements</span> MessageListener to parrot everything received
<span style="color: #000000; font-weight: bold;">class</span> ParrotMessageListener
include org.<span style="color: #006633;">jivesoftware</span>.<span style="color: #006633;">smack</span>.<span style="color: #006633;">MessageListener</span> # implement <span style="color: #000000; font-weight: bold;">interface</span>
&nbsp;
def processMessage<span style="color: #009900;">&#40;</span>chat, message<span style="color: #009900;">&#41;</span> # process_message does not work
chat.<span style="color: #006633;">send_message</span> <span style="color: #0000ff;color: blue;">&quot;Polly says '#{message.body}'?&quot;</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #339933;">!</span>message.<span style="color: #006633;">body</span>.<span style="color: #006633;">empty</span><span style="color: #339933;">?</span>
end
end
&nbsp;
# <span style="color: #000000; font-weight: bold;">Implements</span> MessageListener to print message body to STDOUT
<span style="color: #000000; font-weight: bold;">class</span> StdoutMessageListener
include org.<span style="color: #006633;">jivesoftware</span>.<span style="color: #006633;">smack</span>.<span style="color: #006633;">MessageListener</span>
&nbsp;
def processMessage<span style="color: #009900;">&#40;</span>chat, message<span style="color: #009900;">&#41;</span>
puts <span style="color: #0000ff;color: blue;">&quot;#{chat.participant}: #{message.body}&quot;</span> <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #339933;">!</span>message.<span style="color: #006633;">body</span>.<span style="color: #006633;">empty</span><span style="color: #339933;">?</span>
end
end
end</pre></div></div>

<p>The only thing that tripped me up here was implementing the org.jivesoftware.smack.MessageListener interface. You implement a Java interface by including it in your Ruby class. At first I implemented &#8216;process_message&#8217; instead of &#8216;processMessage&#8217; which is not an entirely unreasonable thing to do given JRuby&#8217;s nice conversion from CamelCase to Ruby conventions in all other cases. The bummer was that I got no errors with that implementation. My listeners just didn&#8217;t receive messages. JRuby&#8217;s proxy implementation should probably do a better job of handling this.</p>
<p><b>chat.rb</b</p>
<p>A script to use this module might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">$:<span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;color: blue;">'/lib/'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;color: blue;">'smack_helper'</span>
<span style="color:#9966CC; font-weight:bold;">include</span> SmackHelper
&nbsp;
debug                      <span style="color:#008000; font-style:italic;"># enable connection debug console</span>
connect <span style="color:#996600;color: blue;">'asalant'</span>, <span style="color:#996600;color: blue;">'****'</span>  <span style="color:#008000; font-style:italic;"># connect to Google Talk and log in</span>
chat <span style="color:#996600;color: blue;">'myfriend'</span>            <span style="color:#008000; font-style:italic;"># chat with myfriend@gmail.com</span>
parrot                     <span style="color:#008000; font-style:italic;"># parrot everything they say</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># read messages from STDIN (empty message ends chat)</span>
<span style="color:#9966CC; font-weight:bold;">while</span> !<span style="color:#006600; font-weight:bold;">&#40;</span>msg = <span style="color:#CC0066; font-weight:bold;">gets</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">empty</span>?
say msg
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
disconnect
<span style="color:#CC0066; font-weight:bold;">exit</span></pre></div></div>

<p>A chat session might look like:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ jruby chat.rb
Chatting with myfriend...
Parroting myfriend.
You there?
myfriend: I am!
myfriend: Did you just repeat me?
No, that's my parrot.
myfriend: Oh. That's lame.
&nbsp;
Disconnected.
$</pre></div></div>

<p><b>irb</b</p>
<p>Or you can use it from irb:</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">$ jruby -S irb
irb(main):001:0&gt; $:&lt;&lt; File.dirname(__FILE__) + '/lib/'
=&gt; [&quot;/usr/local/jruby-1.1RC1/lib/ruby/site_ruby/1.8&quot;,...&quot;]
irb(main):002:0&gt; require 'smack_helper'
=&gt; true
irb(main):003:0&gt; include SmackHelper
=&gt; Object
irb(main):004:0&gt; connect 'asalant', '****'
=&gt; #&lt;Java::OrgJivesoftwareSmack::XMPPConnection:0xb2d8e0 @java_object=org.jivesoftware.smack.XMPPConnection@53f6e6&gt;
irb(main):005:0&gt; chat 'myfriend'
Chatting with myfriend...
=&gt; #&lt;Java::OrgJivesoftwareSmack::Chat:0xdac0d9 @java_object=org.jivesoftware.smack.Chat@52fd52&gt;
irb(main):006:0&gt; say 'you there?'
=&gt; nil
irb(main):007:0&gt; myfriend: I am!
say 'oh, hi.'
=&gt; nil
irb(main):008:0&gt; disconnect
Disconnected.
=&gt; nil
irb(main):009:0&gt; exit</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2008/02/ruby-on-rails/google-talking-with-jruby-and-smack/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JRubyGems Release</title>
		<link>http://blog.carbonfive.com/2008/01/java/jrubygems-release</link>
		<comments>http://blog.carbonfive.com/2008/01/java/jrubygems-release#comments</comments>
		<pubDate>Fri, 04 Jan 2008 19:39:27 +0000</pubDate>
		<dc:creator>alon</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog/?p=20</guid>
		<description><![CDATA[I&#8217;m releasing a first version of JRubyGems. This post is documentation until I come up with something better. JRubyGems allows you to package RubyGems on your Java application classpath. It removes the file system dependencies on locally installed gems that get awkward when using JRuby and dependent gems in a Java environment. Usage Use JRubyGems [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m releasing a first version of JRubyGems. This post is documentation until I come up with something better.</p>
<p>JRubyGems allows you to package RubyGems on your Java application classpath. It removes the file system dependencies on locally installed gems that get awkward when using JRuby and dependent gems in a Java environment.</p>
<p><strong><a name="JRubyGems-Usage"></a>Usage</strong></p>
<p>Use JRubyGems as a replacement for RubyGems. Instead of</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;color: blue;">'rubygems'</span>
gem <span style="color:#996600;color: blue;">'activerecord'</span></pre></div></div>

<p>use</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;color: blue;">'jrubygems'</span>
gem <span style="color:#996600;color: blue;">'activerecord'</span></pre></div></div>

<p>Behind the scenes JRubyGems requires RubyGems and injects behavior specific to finding gems on the Java classpath if they are not already installed.</p>
<p>You make JRubyGems available to your application by putting the jar on your application classpath.</p>
<p><strong><a name="JRubyGems-GetIt"></a>Get It</strong></p>
<p>Source is available from Subversion at <a href="https://svn.carbonfive.com/public/carbonfive/jruby/jrubygems/trunk/">https://svn.carbonfive.com/public/carbonfive/jruby/jrubygems/trunk/</a>. The tests in <a href="https://svn.carbonfive.com/public/carbonfive/jruby/jrubygems/trunk/ruby/test/test_jrubygems.rb">ruby/test/test_jrubygems.rb</a> illustrate JRubyGems&#8217; behavior.</p>
<p>The jar at <a href="http://mvn.carbonfive.com/public/com/carbonfive/jruby/jrubygems/0.3/jrubygems-0.3.jar">http://mvn.carbonfive.com/public/com/carbonfive/jruby/jrubygems/0.3/jrubygems-0.3.jar</a> is all you need to try it out in your own scripts. With JRuby you can require jar files that are in your load path to get them on your classpath and make Ruby files in the jar available on your load path. So if I have a folder lib/ in my load path with the file lib/jrubygems-0.3.jar, I can use JRubyGems directly from a JRuby script with:</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;color: blue;">'jrubygems-0.3.jar'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;color: blue;">'jrubygems'</span></pre></div></div>

<p>Most Java applications using embedded Ruby will have their own classpath management strategy. Just make sure the JRubyGems jar gets on the classpath of your application. If you are using Maven, you can use JRubyGems from the Carbon Five repository:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;repositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;repository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>c5-public-repository<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/id<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>Carbon Five Public Repository<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/name<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>http://mvn.carbonfive.com/public<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/url<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/repository<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/repositories<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
&nbsp;
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.carbonfive.jruby<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>jrubygems<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
    <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>0.3<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependencies<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>If you are using Maven you can also require your JRuby dependency with:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>org.jruby<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>jruby-complete<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.1RC1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p><strong><a name="JRubyGems-PackagingGemDependencies"></a>Packaging Gem Dependencies</strong></p>
<p>JRubyGems expects a gem to be available on your application classpath as a .gem file (the distribution package for a gem) under the classpath location /gems. This means you can have a gems/ folder on your classpath with a bunch of .gem files in it, a jar with all your .gem files under /gems or a jar per .gem file with each file under /gems in each jar. (A limitation in the JDK&#8217;s ClassLoader.getResources method which only returns file system locations for a passed-in empty String prevented me from allowing .gem files in jar roots.)</p>
<p>For our migration application, I built a jar for each gem dependency and deployed it to our central Maven repository. My Maven build references these dependencies in my project POM just as I would a jar dependency.</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;"><span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>com.carbonfive.jruby.gems<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/groupId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>activerecord<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/artifactId<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
  <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1.15.6<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/version<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/dependency<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>I just grabbed the .gem files from my local JRuby installation&#8217;s gem cache dir at jruby-1.1b1/lib/ruby/gems/1.8/cache/ to build these jars for now.</p>
<p><em>I like that <a href="http://raven.rubyforge.org/">Raven</a> takes exactly the opposite approach &#8211; managing jar dependencies as gems.</em></p>
<p><strong><a name="JRubyGems-Background"></a>Background</strong></p>
<p>Christian and I have a side project at Carbon Five to create a standard mechanism for managing database migrations for our Java projects. The first implementation defines a migration as a SQL script to be run against the target database. I thought it would be cool to support ActiveRecord migrations too, especially for providing an easy way to do the data migrations that accompany a schema change.</p>
<p>My prototype of this idea went well (more on that some other time) but I quickly ran into an issue with the gem dependency for &#8216;activerecord-jdbc-adapter&#8217; and its dependencies &#8216;activesupport&#8217; and &#8216;activerecord&#8217;. The issue is that my Java project was nicely portable but the gems create a dependency on the runtime system having specific gems installed. If I install the gems locally, I also have to install them on other runtime systems like our continuous integration server.</p>
<p>I found another example of a JRuby user running into this problem when reading about this example of <a href="http://quickdeck.blogspot.com/2007/07/use-your-favorite-ruby-library-in-java.html">using the RedCloth Ruby library to format text in a Spring/Java application</a>. Note the &#8220;ugly underbelly&#8221; footnote.</p>
<p>In the Ruby world, this is the way things work. Large Ruby applications (especially Rails applications) often rely on system services like cron to do their work. These applications have their own mechanisms for setting up new runtime systems. In the Java world, we expect to package our application with all of its dependencies and deploy it to little more than a JVM and webapp container.</p>
<p>Java has the classpath abstraction to address minimizing file system dependencies while Ruby uses the file system directly and extensively. I&#8217;ve seen a couple approaches for addressing this mismatch between Java and Ruby. All of them involve taking some set of resources packaged in a Java archive (jar, war), extracting it to a file system location at runtime and configuring Ruby to use the resources at that location. The &#8220;jruby-complete&#8221; JRuby distribution unpacks the core Ruby libraries into ~/.jruby/. <a href="http://wiki.jruby.org/wiki/Goldspike">GoldSpike</a>, the Rails plugin for packaging Rails applications as war files, bundles gems in WEB-INF and configures GEM_HOME at runtime to use the gems from the unpacked war.</p>
<p>I decided to take a similar approach with JRubyGems &#8211; bundle gem dependencies in the application classpath and install them on the local file system on demand if they are not already available. As I expect happens with many JRuby projects, it took a little Java and a little Ruby and works quite well.</p>
<p><strong><a name="JRubyGems-HowItWorks"></a>How It Works</strong></p>
<p>The main flow for RubyGems to load a gem that has not yet been loaded for an application is:</p>
<ol>
<li>Kernel::gem</li>
<li>Kernel::activate_gem_with_options</li>
<li>Gem.activate</li>
<li>Gem.source_index.find_name</li>
<li>Gem.activate each dependency of this gem first</li>
<li>Finish activating this gem</li>
</ol>
<p>JRubyGems replaces the Gem.activate implementation to insert a couple steps that:</p>
<ol>
<li>Check if the gem is locally installed</li>
<li>Search the Java classpath for the gem source if not installed</li>
<li>Install the gem locally</li>
<li>Continue with the base Gem.activate implementation</li>
</ol>
<p>This ensures that gems and their transitive dependencies are installed and loaded.</p>
<p>The classpath searching is implemented in Java.</p>
<p><strong>Release History</strong></p>
<p><em>0.3 2008-01-28</em></p>
<ul>
<li>Upgrade to use JRuby 1.1RC1 and RubyGems 1.0.1 (bundled with 1.1RC1)</li>
<li>Added test for gem that bundles a jar in lib/ (hpricot)</li>
</ul>
<p><em>0.2 2008-01-07</em></p>
<ul>
<li>Resolved issues with transitive dependency installation</li>
<li>Force install of classpath gems to avoid dependency errors</li>
<li>Additional logging of install locations</li>
</ul>
<p><em>0.1 2008-01-04</em></p>
<p>Initial release.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2008/01/java/jrubygems-release/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Thoughts on JRuby</title>
		<link>http://blog.carbonfive.com/2008/01/java/thoughts-on-jruby</link>
		<comments>http://blog.carbonfive.com/2008/01/java/thoughts-on-jruby#comments</comments>
		<pubDate>Wed, 02 Jan 2008 21:00:47 +0000</pubDate>
		<dc:creator>alon</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog/?p=19</guid>
		<description><![CDATA[At Carbon Five we have built our professional consulting practice on the solid foundation of enterprise Java development. In 2007 we added Ruby and Ruby on Rails as development tool and framework that complement our existing values and process in many fantastic ways. Looking forward, I want to be sure that we take maximum advantage [...]]]></description>
			<content:encoded><![CDATA[<p>At Carbon Five we have built our professional consulting practice on the solid foundation of enterprise Java development. In 2007 we added Ruby and Ruby on Rails as development tool and framework that complement our existing values and process in many fantastic ways.</p>
<p>Looking forward, I want to be sure that we take maximum advantage of our existing knowledge and new learning in both Java and Ruby. I have high hopes for <a href="http://jruby.codehaus.org/">JRuby</a> as a valuable bridge that spans both languages and gives developers the flexibility to use the strengths of the two. Sun appears to feel the same way as <a href="http://headius.blogspot.com/2006/09/jruby-steps-into-sun.html">they have hired the two core JRuby developers</a>, <a href="http://headius.blogspot.com/2007/11/top-five-questions-i-get-asked.html">Charles Nutter</a> and Thomas Enebo, to work on JRuby full time.</p>
<p>In preparation for more specific posts, here are some light musings on JRuby.</p>
<p><b><a name="JRuby-JRuby1.0"></a>JRuby 1.0</b></p>
<p>Released mid-2007 JRuby 1.0 was focused on Ruby compatibility. The idea is that any Ruby script or application you can run with the native C Ruby interpreter, you can run with JRuby. The success of this effort can be observed with Ruby on Rails applications <a href="http://oracleappslab.com/2007/11/21/mix-jruby-on-rails-small-teams-agile-and-its-effects-on-the-world/">now running on JRuby</a>. Of course, there are <a href="http://jruby.codehaus.org/Limitations">some limitations</a>.</p>
<p>In addition to running pure Ruby, JRuby can access the Java environment in which it is running. You get the Ruby niceties that you would expect like optional conversion of CamelCase method names to underscore_separated.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">list = java.<span style="color:#9900CC;">util</span>.<span style="color:#9900CC;">ArrayList</span>.<span style="color:#9900CC;">new</span>
list.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;color: blue;">&quot;one&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
list.<span style="color:#9900CC;">add_all</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">2</span>, <span style="color:#996600;color: blue;">&quot;three&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>Any Java classes in the Java classpath are available to your JRuby script. Additionally, you can &#8216;require foo.jar&#8217; to make it available on your classpath at runtime. </p>
<p>You can also extend Java classes in JRuby.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> MyList <span style="color:#006600; font-weight:bold;">&lt;</span> java.<span style="color:#9900CC;">util</span>.<span style="color:#9900CC;">ArrayList</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> say_hi
    <span style="color:#996600;color: blue;">&quot;hi&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Internally, many core Ruby classes have been rewritten to delegate to core Java classes.</p>
<p><b><a name="JRuby-JRuby1.1"></a>JRuby 1.1</b></p>
<p>JRuby 1.1 is presently in beta. The top priorities for JRuby 1.1 are performance and Java integration. Ruby is not fast. JRuby 1.0 was worse. Performance was not a priority for 1.0 and the consensus is that there are a lot of easy performance wins that it is now time to take advantage of. <a href="http://headius.blogspot.com/2007/11/top-five-questions-i-get-asked.html">In his blog</a>, Charles Nutter states:</p>
<p>
<blockquote>
Straight-line execution is now typically 2-4x better than Ruby 1.8.6. Rails whole-app performance ranges from just slightly slower to slightly better, though there have been reports of specific apps running many times faster.
</p></blockquote>
<p><b><a name="JRuby-JavaIntegration"></a>Java Integration</b></p>
<p>Java integration refers to features for the using Ruby from Java rather than Java from Ruby as I discuss above. When I first started looking at JRuby Christian and I were working on a Java library to manage database migrations ala RoR and some other neat tricks we&#8217;ve seen along the way. (More on that later.) I thought it would be cool if you could write migrations using ActiveRecord&#8217;s migration features and invoke them from Java. I found myself looking for the easy means to invoke Ruby from Java. Some of this is in place with more slated for future JRuby versions. </p>
<p>The Spring Framework provides JRuby integration through which you can expose Ruby classes as Spring-managed beans. This example of <a href="http://quickdeck.blogspot.com/2007/07/use-your-favorite-ruby-library-in-java.html">using the RedCloth Ruby library to format text in a Java application</a> is a pretty slick example of how this works.</p>
<p>This post does point out one issue that I ran into with using Ruby from Java &#8211; RubyGems. Gems are Ruby libraries available from central repositories and installed on the system running Ruby. For Java applications, this dependency on system-installed resources is lame. To address this issue, I&#8217;ve spent some time working on a solution for <a href="http://www.nabble.com/Proposal-for-managing-gem-dependencies-in-a-Java-%2B-JRuby-application-to14161350.html#a14223747">packaging Ruby gem dependencies in Java applications</a>. More on JRubyGems coming soon.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2008/01/java/thoughts-on-jruby/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby on Rails Project Report</title>
		<link>http://blog.carbonfive.com/2007/09/ruby-on-rails/ruby-on-rails-project-report</link>
		<comments>http://blog.carbonfive.com/2007/09/ruby-on-rails/ruby-on-rails-project-report#comments</comments>
		<pubDate>Mon, 10 Sep 2007 22:17:17 +0000</pubDate>
		<dc:creator>alon</dc:creator>
				<category><![CDATA[Ruby (on Rails)]]></category>

		<guid isPermaLink="false">http://blog/?p=18</guid>
		<description><![CDATA[Randy and I recently completed a project implemented with Ruby on Rails. This is a writeup of the tools and strategies we used and what we learned, liked and disliked about Rails development. What We Did The project was fairly small; we pair-programmed almost all of the development, totaling about 10 person weeks of work. [...]]]></description>
			<content:encoded><![CDATA[<p>Randy and I recently completed a project implemented with Ruby on Rails. This is a writeup of the tools and strategies we used and what we learned, liked and disliked about Rails development.</p>
<h2 style="font-size:14px; margin: 10px 0 0 0">What We Did</h2>
<p>The project was fairly small; we pair-programmed almost all of the development, totaling about 10 person weeks of work. The application replaces a hybrid FileMaker/Excel solution our client was using to collect and analyze research data on corporate practices. The application is used by a small number of users (&lt;10) but all day, every day.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Development</h3>
<p>We did our development on OS X using <a href="http://www.jetbrains.com/idea/nextversion">IntelliJ IDEA 7 beta</a> with the <a href="http://www.jetbrains.net/confluence/display/RUBYDEV/IntelliJ+IDEA+Ruby+Plugin">Ruby plugin</a>. While we suffered bleeding edge instability issues with some plugin versions, IDEA and the Ruby plugin were great tools providing support for rake, RDoc, unit testing, and running our development server. The PDF version of <a href="http://www.pragmaticprogrammer.com/title/rails/">Agile Web Development with Rails</a> was our bible for reference information.</p>
<p>We used <a href="http://www.atlassian.com/software/bamboo/">Atlassian Bamboo</a> for continuous integration since we are already using it for our Java projects. The <a href="http://furiouspurpose.blogspot.com/2007/07/ruby-on-rails-continuously-integrated.html">ci_reporter</a> and <a href="http://furiouspurpose.blogspot.com/2007/07/bamboo-ruby-on-rails-test-reports-and.html">rails_rcov</a> Rails plugins provide test and code coverage information to Bamboo&#8217;s statistics database.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Deployment</h3>
<p>We hosted our staging server at Carbon Five running a pack of Mongrels with Apache mod_proxy_balancer. Our production server is hosted at Joyent (aka TextDrive).</p>
<p>We used <a href="http://rubyforge.org/projects/capistrano/">capistrano and capistrano-ext</a> to manage deployment to multiple targets (staging and production).</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">REST</h3>
<p>We jumped straight in to using the Rails 2.0 RESTful support. To our surprise we found the scaffolding created by &#8216;script/generate scaffold_resource Foo&#8217; to be very helpful from UI to database including a starting point for building out our tests. We used nested resources and custom actions. We used content-type/format detection to return different views for the same actions.</p>
<p>If you are going to use REST on Rails you have to understand Rails routes. Of all aspects of the Rails framework, understanding request routing and the finer details of the generated helper methods caused us the most head scratching moments. Writing unit tests for our routes.rb file was a helpful tool for answering questions.</p>
<p>Without a doubt, REST is the way to go in Rails. It creates a sense of context within your application and a taxonomy of the actions that can take place. The helper methods for generating paths simplify refactoring and reorganizing.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Plugins</h3>
<p>In general we found the quality of available plugins to be high and their functionality rich. Plugins provide a range of functionality from extensions to ActiveRecord, mixins, rake tasks, and generators for migrations, models and controllers. Things are changing fast so it is important to survey the available options. Sometimes the most discussed plugin is not the best to use &#8211; just the one that has been available the longest.</p>
<p>We used <a href="http://piston.rubyforge.org/usage.html">Piston</a> to manage our plugin dependencies. The standard Rails practice of using svn:externals linked to the trunk of a plugin&#8217;s development seemed sketchy to us. In fact, the trunk of the restful_authentication plugin had recent changes that caused it to fail in anything but Edge Rails. We used Piston to lock the plugin to the last working version. It&#8217;s strange to me that plugin developers do not seem to use tags and branches to manage releasing their plugins to the world.</p>
<p>The <a href="http://blog.evanweaver.com/files/doc/fauna/has_many_polymorphs/files/README.html">has_many_polymorphs plugin</a> extends Rails&#8217; associations with advanced support for polymorphic associations. We used this plugin to implement tagging features in place of the older, less flexible acts_as_taggable plugin. The plugin also provides a generator for specifically implementing tagging.</p>
<p>The <a href="http://delynnberry.com/projects/userstamp">userstamp plugin</a> automatically updates &#8216;created_by&#8217; and &#8216;updated_by&#8217; attributes of model objects with the logged in user.</p>
<p>The <a href="http://wiki.rubyonrails.org/rails/pages/ActsAsVersioned">acts_as_versioned plugin</a> provides versioning of a subset of our model objects. We have a complex hierarchy for research information that can change through time. Research from a point in time needs to match the hierarchy at that time. The acts_as_versioned plugin manages a table of versions for each model being versioned with mixed-in methods on the model objects for accessing historical versions.</p>
<p>The <a href="http://agilewebdevelopment.com/plugins/restful_authentication">restful_authentication plugin</a> provides user authentication. The <a href="http://www.writertopia.com/developers/authorization">authorization plugin</a> provides role and instance-based authorization. The authorization plugin implements a lightweight DSL &#8211; a technique that seems to be favored by many Ruby developers. The authorization plugin exposed us to the practice of using static class members as thread-local instances. We couldn&#8217;t quite stomach having User.current_user statically defined so implemented it with a thread-local instance:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">current_user</span>=<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</span><span style="color:#006600; font-weight:bold;">&#93;</span> = user
  <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;">current_user</span>
    <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">current</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user</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;">end</span></pre></div></div>

<p>We wrote our own acts_as_notable plugin using the core plugin generator and the <a href="http://wiki.rubyonrails.com/rails/pages/HowToWriteAnActsAsFoxPlugin">HOWTO</a> on the Rails wiki. Our plugin mixes-in the ability to add notes to any model object. This was our first exposure to the powerful meta-programming tools &#8216;class_eval&#8217; and &#8216;instance_eval&#8217;. We later realized that we could have used the has_many_polymorphs plugin for this but the exercise implementing this plugin was valuable anyway.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Testing</h3>
<p>We used the core Rails support for unit, functional and integration tests though, honestly, we didn&#8217;t write any integration tests. We did not use RSpec or Mocha so did not get into behavior-based testing for Rails.</p>
<p>In general we found the testing support in Rails to be great. Being able to make assertions on your HTML output with &#8216;assert_select&#8217; is great. Even simply having exceptions raised in output rendering when we broke a view with a refactor was great. Coming from the Java world where JSP makes it very difficult to get HTML output outside of the container, controller (functional) testing was a breath of fresh air.</p>
<p>Rails data fixtures are pretty cool but also a pain in the butt. In Java land, we use <a href="http://dbunit.sourceforge.net/">DBUnit</a> to create data fixtures that model an application scenario for a suite of tests. With the core Rails support for fixtures, you are stuck maintaining a monolithic fixture context with related information spread across multiple files. Our application is a small one but even so our fixtures quickly became hard to manage and understand. Adding a version dimension to our model data didn&#8217;t help.</p>
<p>One approach we have seen for maintaining fixtures in to write a suite of tests that assert the integrity of your fixture data. Keep your fixtures as lean as possible while representing all possible application states. Yuck. We are interested in using <a href="http://errtheblog.com/post/7708">fixture scenarios</a> on our next project.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Rake</h3>
<p>Randy dropped a database.rake file into lib/tasks/ to give us some utilities for managing our databases. While in early development, we would occasionally modify a historical migration and recreate our database from scratch using db:reset.</p>
<p>We also created a project rake file that defined tasks for importing data into our system. The import could have been a migration but seemed better as a task that could be done or redone at any time.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Migrations</h3>
<p>We like migrations a lot. We like the Rails DSL for defining migrations, using model objects in migrations, and explicit schema versioning. In fact, we liked migrations so much that we implemented a similar strategy on our Java projects over a year ago.</p>
<p>We did debate a couple issues. First, is it ever okay to modify historical migrations, for example, to add a column to a model. I felt that if a build has been pushed to our staging server, we should never modify a historical migration. We should have to migrate our staging data forward just like our production data. In that way we get to stage our migrations too. In reality, it turned out that it was only really important to be disciplined about this once we had a production system with data that we could not lose.</p>
<p>The other issue we debated was how much time to spend on our &#8216;down&#8217; migrations. There are plenty of scenarios where you could roll back the schema but lose data. What do you do in this case? In reality, our deployment architecture and roll out plans were so simple that down migrations did not really seem relevant for this application. In the end we did test that our migrations could go up and down and preserved data where it was easy but did not spend much time on it. Do people implement <a href="http://spin.atomicobject.com/2007/02/27/migration-testing-in-rails/">migration tests</a>?</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Prototype for AJAX</h3>
<p>Both Randy and I are very comfortable writing good object-oriented JavaScript for AJAX behaviors. For this project, we decided to try to use the <a href="http://api.rubyonrails.org/classes/ActionView/Helpers/PrototypeHelper.html">Rails Prototype helper methods</a> to best understand its strengths and weaknesses. For this project we use AJAX for inline page updates and found the Prototype helper support to be fine. I liked the consistent syntax for expressing AJAX calls, form posts and HTML links. Randy thought it would have been easier to use Prototype directly than learn the thin Rails wrappers.</p>
<h2 style="font-size:14px; margin: 10px 0 0 0">What We Liked</h2>
<p>From the discussion above:</p>
<ul>
<li>RESTful Rails</li>
<li>Migrations</li>
<li>HTML assertions in functional tests</li>
<li>capistrano</li>
<li>Mixins</li>
<li><a href="http://www.pragmaticprogrammer.com/title/rails/">Agile Web Development with Rails</a></li>
</ul>
<p>Also, we like Ruby. It is terse yet semantically expressive. We often found ourselves writing six lines of code that we would reduce down to one intuitive and easy-to-read line. Ruby has a great shape-changing ability that makes it easy to create lightweight DSLs for different contexts. Rails makes great use of this ability in database migrations and RJS templates. We liked mixins and found them far more useful than inheritance for our purposes.</p>
<h2 style="font-size:14px; margin: 10px 0 0 0">What We Didn&#8217;t Like</h2>
<h3 style="font-size:12px; margin: 10px 0 0 0">Dependency Management</h3>
<p>As mentioned above, we used Piston to manage our plugin dependencies. Where possible we also installed Gems in vendor/. In many cases, you need Gems to be built and installed for your system so you cannot check them in. </p>
<p>We ran into one issue where the plugins we we needed for our continuous integration server had gem dependencies that caused our application to not load in any environment, even if we did not need those plugins or gems for that environment. The issue was the way that rake tasks in the plugins loaded their dependencies. We ended up having to modify the plugins to not load if the gems were not available.</p>
<p>This dependency on system-installed software was foreign and awkward coming from Java land. Rails applications often depend on other system software like cron and ImageMagik. You can imagine multiple Rails applications running on one server having gem or software version conflicts. It seems that virtualization solutions could be very helpful here as it is for LAMP-based applications. We worked on a Python project that included a VMWare image of the entire development environment checked in to source control. It turned out to be a slick solution to the system dependency problem.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Foreign Keys</h3>
<p>Rails does not have built in support for foreign keys. In your migrations, you have to execute SQL to create and remove foreign keys. Plenty of folks in the Rails community seem to think they are a good idea but there are issues. One issue we ran in to was that &#8216;db:test:prepare&#8217; which replicates your database schema for testing does not replicated foreign keys so you can create scenarios that succeed in tests but fail in production.</p>
<p>On the other hand, not having foreign keys when testing made fixtures a bit easier to manage since load order did not matter.</p>
<p>We ended maintaining that foreign keys are important but that not having them in test was okay. </p>
<h3 style="font-size:12px; margin: 10px 0 0 0">ActiveRecord Queries</h3>
<p>Coming from Hibernate, we found the query-building facilities of ActiveRecord to be limited. Very quickly you end up doing a bunch of string-munging to build dynamic queries. <a href="http://www.pivotalblabs.com/articles/2007/09/02/hasfinder-its-now-easier-than-ever-to-create-complex-re-usable-sql-queries">has_finder</a> looks like it may address some of these issues.</p>
<h3 style="font-size:12px; margin: 10px 0 0 0">Refactoring</h3>
<p>After years using IDEA for Java development, it was a bit odd to be back in the world of search-and-replace for rename refactors. The IDEA Ruby plugin support for refactoring is improving but still needs work to be generally useful. </p>
<p>The most important lesson we learned in regards to refactoring is to be diligent about naming classes, methods and variables to be consistent with the model names and inflections of your application. Don&#8217;t abbreviate. Avoid model objects where the plural is the same as the singular because renaming it later will be harder than if the forms are different.</p>
<p>After using a good refactoring tool to work on Java applications going on four and five years old, I am bit worried about what its going to be like to work on Rails applications that have been around that long. Hopefully the tool support will be there but it will never be as good for a scripting language as it is for Java. Basic refactors like renaming are only going to take longer as a Rails application grows. Keep your test coverage high and refactor regularly or you may find yourself in the regrettable circumstance where the cost of refactoring prevents you from doing it. </p>
<h2 style="font-size:14px; margin: 10px 0 0 0">Looking Forward</h2>
<p>On our next project we are looking forward to:</p>
<ul>
<li>SOLR for searching</li>
<li>RSpec or Mocha for behavior-based testing</li>
<li>fixtures-scenarios</li>
<li>Debugging in IDEA</li>
<li><a href="http://redhanded.hobix.com/inspect/markabyForRails.html">Markaby</a> for page markup</li>
<li><a href="http://www.pivotalblabs.com/articles/2007/09/02/hasfinder-its-now-easier-than-ever-to-create-complex-re-usable-sql-queries">has_finder</a> for query building</li>
<li>Digging into the ActiveRecord source</li>
<li><a href="http://www.railsenvy.com/2007/2/28/rails-caching-tutorial">Page caching</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.carbonfive.com/2007/09/ruby-on-rails/ruby-on-rails-project-report/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
