<?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>SmartLogic Solutions Blog &#187; rails</title>
	<atom:link href="http://blog.smartlogicsolutions.com/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.smartlogicsolutions.com</link>
	<description>News and updates from the people at SmartLogic Solutions</description>
	<lastBuildDate>Tue, 30 Nov 2010 21:39:14 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Setting Up Ubuntu 9.10 for Ruby On Rails Development</title>
		<link>http://blog.smartlogicsolutions.com/2010/02/01/setting-up-ubuntu-9-10-for-ruby-on-rails-development/</link>
		<comments>http://blog.smartlogicsolutions.com/2010/02/01/setting-up-ubuntu-9-10-for-ruby-on-rails-development/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 21:09:31 +0000</pubDate>
		<dc:creator>Adam Bachman</dc:creator>
				<category><![CDATA[Adam Bachman]]></category>
		<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Passenger]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby Enterprise Edition]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[ubuntu]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[environment]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=860</guid>
		<description><![CDATA[This is a document I put together at the beginning of 2010 while building yet another Ubuntu VM, digging through our internal documentation to try and find out what I needed. We've got the answers, and generally Ruby, Rails, and Ubuntu are pretty good about telling you how to install tools if you don't have them yet.

But the answers are spread out and distributed randomly. Plus, I can only see "The program '______' is currently not installed. You can install it by typing: sudo apt-get install ______" so many times before I lose interest and put off the task.

So, to prevent future headaches and help all of us out, I put together a how-to that can take a new Rails system from zero to code in a few minutes (depending on network speed) instead of half a day.]]></description>
			<content:encoded><![CDATA[<p>This is a document I put together at the beginning of 2010 while building yet another Ubuntu VM, digging through our internal documentation to try and find out what I needed. We&#8217;ve got the answers, and generally Ruby, Rails, and Ubuntu are pretty good about telling you how to install tools if you don&#8217;t have them yet.</p>
<p>But the answers are spread out and distributed randomly. Plus, I can only see &#8220;The program &#8216;______&#8217; is currently not installed. You can install it by typing: sudo apt-get install ______&#8221; so many times before I lose interest and put off the task.</p>
<p><span id="more-860"></span></p>
<p>So, to prevent future headaches and help all of us out, I put together a how-to that can take a new Rails system from zero to code in a few minutes (depending on network speed) instead of half a day. With no further ado,</p>
<h2>Setting up an Ubuntu box for Rails Development (including virtual machines)</h2>
<h4>Update everything</h4>
<pre>$ sudo aptitude update &amp;&amp; sudo aptitude dist-upgrade</pre>
<h4>Install necessary packages</h4>
<pre>$ sudo aptitude install build-essential vim \
  vim-runtime git-core subversion libsqlite3-dev</pre>
<p>We have projects in git (the newer ones) and svn, so we have to be able to switch fluidly between the two.</p>
<p>And I&#8217;m not trying to start a flame war, but Vim is the first choice for Rails development. You don&#8217;t have to take my word for it; <a href="http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim">Jamis Buck</a>, <a href="http://github.com/tpope">Tim Pope</a>, and <a href="http://www.adamlowe.me/2009/12/vim-destroys-all-other-rails-editors.html">Adam Lowe</a> all say the same. I recommend the NERDTree, FuzzyFinderTextMate, BufExplorer, and rails.vim plugins if nothing else.</p>
<h4>Install ruby</h4>
<pre>$ sudo aptitude install ruby1.8 ruby rdoc ruby1.8-dev \
  libpgsql-ruby1.8 libmysql-ruby1.8 irb libopenssl-ruby</pre>
<h4>Get rubygems from source. <a href="http://docs.rubygems.org/">http://docs.rubygems.org/</a></h4>
<pre>$ wget http://rubyforge.org/frs/download.php/60718/rubygems-1.3.5.tgz</pre>
<pre>$ tar xzvf rubygems-1.3.5.tgz</pre>
<pre>$ cd rubygems-1.3.5</pre>
<pre>$ sudo ruby setup.rb</pre>
<pre>$ sudo ln -s /usr/bin/gem1.8 /usr/bin/gem</pre>
<pre>$ sudo gem update --system</pre>
<h4>Update ~/.gemrc (at least the :sources: chunk)</h4>
<pre>---
gem: --no-ri --no-rdoc
:benchmark: false
:verbose: true
:backtrace: false
:update_sources: true
:sources:
- http://gemcutter.org
- http://gems.rubyforge.org/
- http://gems.github.com</pre>
<h4>Install and setup Passenger (optional)</h4>
<pre>$ sudo apt-get install apache2-prefork-dev</pre>
<pre>$ sudo gem install passenger</pre>
<pre>$ sudo passenger-install-apache2-module</pre>
<p>and follow the instructions passenger gives you. Most folks in the office run some form of an Apache-Passenger stack for development purposes. I can explain how that setup works in a future post.</p>
<h4>Install geminstaller</h4>
<pre>$ sudo gem install geminstaller</pre>
<p>Almost all of our legacy projects use <a href="http://geminstaller.rubyforge.org/">geminstaller</a> to manage gem dependencies. In the future, new projects will be moving to <a href="http://github.com/wycats/bundler">Bundler</a>, but legacy projects matter and upgrading subsystems is not always justified.</p>
<p>&#8220;If it ain&#8217;t broke, don&#8217;t fix it&#8221; and the corollary: &#8220;because you probably won&#8217;t be able to bill it to the client&#8221; both apply.</p>
<h4>Install common packages (optional, may be required by projects)</h4>
<pre>$ sudo aptitude install imagemagick</pre>
<pre>$ sudo gem install utility_belt open_gem redgreen</pre>
<p>The first (imagemagick) is used by the Paperclip gem to manage files attached to Rails models. The second are tools that make Rails development more manageable on the command line. I highly recommend them. Besides, I&#8217;ve been sneaking redgreen in as a test dependency on our projects, so if you&#8217;re a developer here you&#8217;ll have to install it anyways.</p>
<h4>Create an ssh key (follow instructions)</h4>
<pre>$ ssh-keygen</pre>
<h3>EXAMPLE PROJECT</h3>
<p>All the stuff above won&#8217;t let you test-code-deploy without hassles, so here&#8217;s a sample run through of what the last mile of project-specific setup looks like.</p>
<h4>Get the project. SVN, Git, whatever. Go to it.</h4>
<pre>$ svn co rails-project</pre>
<pre>$ cd rails-project</pre>
<h4>Run geminstaller</h4>
<pre>$ sudo geminstaller                                 # normal</pre>
<pre>$ sudo geminstaller -c config/test/geminstaller.yml # test env</pre>
<h4>Install necessary aptitude packages</h4>
<pre>$ sudo aptitude install texlive-latex-base</pre>
<p>Don&#8217;t ask.</p>
<h4>Create the test database</h4>
<p>Mysql:</p>
<pre>$ rake RAILS_ENV=test db:create</pre>
<p>Postgres (using your username or DB username in place of &#8220;username&#8221;):</p>
<pre>$ sudo -u postgres psql</pre>
<pre>postgres=# CREATE USER username SUPERUSER;</pre>
<pre>postgres=# CREATE DATABASE username OWNER username;</pre>
<p>If you get an error regarding PGconn.quote_ident (Rails 2.3.x on Ubuntu 8.04) patch <code>activerecord-2.3.4/lib/active_record/connection_adapters/postgresql_adapter.rb</code> and add the following:</p>
<pre>def PGconn.quote_ident(name)
  %("#{name}")
end</pre>
<p>immediately after the &#8220;class PGresult&#8221; definition at the top of the file. Once that&#8217;s all done, the following:</p>
<pre>$ rake RAILS_ENV=test db:create</pre>
<pre>$ rake RAILS_ENV=test db:schema:load</pre>
<pre>$ rake RAILS_ENV=test test</pre>
<p>should work.</p>
<h3>go have fun, write code, blow our minds</h3>
<p>So that&#8217;s how we roll. Awkward requirements will still crop up as we pick up new projects (or very old projects) so you&#8217;ll always need a bit of apt/gem fu to get you through the day. Leave questions here or drop me a line at <a href="mailto:adam@smartlogicsolutions.com">adam@smartlogicsolutions.com</a> or <a href="http://twitter.com/abachman">http://twitter.com/abachman</a>.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/07/07/i-cant-upgrade-rubygems-from-111-to-120-on-ubuntu/" rel="bookmark" class="crp_title">I can&#8217;t upgrade RubyGems from 1.1.1 to 1.2.0 on Ubuntu</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/26/integrity-ci-on-passenger-222-with-ruby-enterprise-edition-on-ubuntu-804/" rel="bookmark" class="crp_title">Integrity CI on Passenger 2.2.2 with Ruby Enterprise Edition on Ubuntu 8.04</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/01/14/aptinstaller-032-released/" rel="bookmark" class="crp_title">Aptinstaller 0.3.2 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/08/04/introducing-environmentalize-an-intuitive-environment-focused-config-structure-for-your-rails-applications/" rel="bookmark" class="crp_title">Introducing environmentalist: an intuitive, environment-focused config structure for your rails applications</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/06/deploying-rails-apps-with-capistrano-without-root-or-sudo-privileges/" rel="bookmark" class="crp_title">Deploying Rails Apps with Capistrano without root or sudo Privileges</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2010/02/01/setting-up-ubuntu-9-10-for-ruby-on-rails-development/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Including external .rake files in your project&#8217;s Rakefile &#8212; keep your rake tasks organized!</title>
		<link>http://blog.smartlogicsolutions.com/2009/05/26/including-external-rake-files-in-your-projects-rakefile-keep-your-rake-tasks-organized/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/05/26/including-external-rake-files-in-your-projects-rakefile-keep-your-rake-tasks-organized/#comments</comments>
		<pubDate>Tue, 26 May 2009 14:58:07 +0000</pubDate>
		<dc:creator>Glenn Gentzke</dc:creator>
				<category><![CDATA[Glenn Gentzke]]></category>
		<category><![CDATA[Rake]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rake task]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=649</guid>
		<description><![CDATA[Perhaps you have a non-Rails project (let&#8217;s say it&#8217;s in ruby and maybe some other languages, too) and you use Rake tasks to automate some of the dirty work. So you&#8217;ve got a bunch of methods that you wish to keep neatly sorted into .rake files in some dir&#8217;s (probably a sub folder of lib [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps you have a non-Rails project (let&#8217;s say it&#8217;s in ruby and maybe some other languages, too) and you use Rake tasks to automate some of the dirty work.  So you&#8217;ve got a bunch of methods that you wish to keep neatly sorted into .rake files in some dir&#8217;s (probably a sub folder of lib like lib/tasks) and a single Rakefile in your project&#8217;s root directory.  Including those external .rake files in your project&#8217;s Rakefile via <strong>require</strong> statements won&#8217;t work :</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;">'lib/some_rake_file'</span> <span style="color:#008000; font-style:italic;"># or require 'lib/some_rake_file.rake'</span></pre></div></div>

<p><em>=> rake aborted!<br />
no such file to load &#8212; /home/your_project/lib/some_rake_file</em></p>
<p>Rake assumes the &#8216;require&#8217;d files end in .rb, so it won&#8217;t find your .rake files.  You need to <strong>import</strong> rake files:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">import <span style="color:#996600;">'lib/some_rake_file'</span></pre></div></div>

<p>  This is fine for individual files, but I wanted to include all files that end in .rake in my tasks dir:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">glob</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'tasks/*.rake'</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>r<span style="color:#006600; font-weight:bold;">|</span> import r <span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p>&#8230;and there you go.  While dead simple, this exemplifies an important distinction between require and import that I found to be poorly documented.  Keep your rake tasks organized and remember that Rake isn&#8217;t just for rails apps!</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/04/04/environmentalist-023-released-supports-rails-232/" rel="bookmark" class="crp_title">environmentalist 0.2.3 released &#8212; supports rails 2.3.2</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/15/automating-flex-compilation-using-ant/" rel="bookmark" class="crp_title">Automating Flex Compilation Using ANT</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/26/integrity-ci-on-passenger-222-with-ruby-enterprise-edition-on-ubuntu-804/" rel="bookmark" class="crp_title">Integrity CI on Passenger 2.2.2 with Ruby Enterprise Edition on Ubuntu 8.04</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/05/13/directory-conventions-for-rack-middleware-rubygems/" rel="bookmark" class="crp_title">Directory Conventions for Rack Middleware RubyGems</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/02/better-setup-for-environments-in-rails/" rel="bookmark" class="crp_title">Better setup for environments in Rails</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/05/26/including-external-rake-files-in-your-projects-rakefile-keep-your-rake-tasks-organized/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Find the Unique Sessions for a Rails Application</title>
		<link>http://blog.smartlogicsolutions.com/2009/05/04/find-the-unique-sessions-for-a-rails-application/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/05/04/find-the-unique-sessions-for-a-rails-application/#comments</comments>
		<pubDate>Mon, 04 May 2009 15:32:47 +0000</pubDate>
		<dc:creator>Nick Gauthier</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Nick Gauthier]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[log files]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[ubuntu]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=617</guid>
		<description><![CDATA[Today we&#8217;re going to look at how to find the number of unique sessions over a specific time frame for a rails application. We&#8217;ll be using the slow-actions gem. Slow-Actions is great tool for determining the slow areas of a rails application. Since it is built on a rails log parser, it can be used [...]]]></description>
			<content:encoded><![CDATA[<p>Today we&#8217;re going to look at how to find the number of unique sessions over a specific time frame for a rails application. We&#8217;ll be using the <a href="http://github.com/ngauthier/slow-actions/tree/master">slow-actions</a> gem.</p>
<p><span id="more-617"></span></p>
<p>Slow-Actions is great tool for determining the slow areas of a rails application. Since it is built on a rails log parser, it can be used for many other things. For example, here is some standard output from slow-actions when you want to know the speed of different user sessions within a specific date range:</p>
<pre>
slow-actions log/development.log --sessions --start-date=2009-03-01 --end-date=2009-04-01
           Cost    Average Max
+ ece0e17b48a5fe0fc766fa42f199fb66 (51 entries, 58% Error)
| Total:   2883.262 732.948 3100.00
| Render:  0.00000 0.00000 0.00000
| DB:      55.8220 14.1900 99.0000 

+ e1181ad94b34b41aff2a74ee62d5fb57 (10 entries, 30% Error)
| Total:   1563.912 676.276 1426.00
| Render:  0.00000 0.00000 0.00000
| DB:      14.5350 6.28500 19.0000 

+ 867bc340e6d65e673f29c57189feaf2b (133 entries, 0% Error)
| Total:   1083.138 221.450 386.000
| Render:  0.00000 0.00000 0.00000
| DB:      44.2030 9.03700 90.0000 

Etc...
</pre>
<p>Now, if we grep for &#8220;entries&#8221; we get a line for each session:</p>
<pre>
slow-actions log/development.log --sessions --start-date=2009-03-01 --end-date=2009-04-01 | grep entries
+ ece0e17b48a5fe0fc766fa42f199fb66 (51 entries, 58% Error)
+ e1181ad94b34b41aff2a74ee62d5fb57 (10 entries, 30% Error)
+ 867bc340e6d65e673f29c57189feaf2b (133 entries, 0% Error)
+ 99b39c7a9af55fc01056b5f127dc4c98 (75 entries, 0% Error)
+ 6ee15c4f3bc804ac68e9e868d9c3f7e6 (14 entries, 0% Error)
+ 80928c25c83590c4f89b91f8d4c8896d (9 entries, 0% Error)
+ c78cfa1cb086b3f473015b212ca3da11 (12 entries, 0% Error)
+ 48cd02cf6544493077c84eb16821bda2 (3 entries, 66% Error)
+ ac027817dcf87d473efb54cd737b2a80 (2 entries, 0% Error)
+ dff2ca2678852b06bbb6c7ca0a85b0a9 (1 entries, 0% Error)
+ 08ed3bc031c23bd3b2572ef7ce60d066 (1 entries, 0% Error)
</pre>
<p>Pipe that to word count, and we have the number of unique sessions within a specified time period:</p>
<pre>
slow-actions log/development.log --sessions --start-date=2009-03-01 --end-date=2009-04-01 | grep entries | wc -l
11
</pre>
<p>On a 54m log file, that takes only 0.761s!</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/03/13/slow-actions-in-rails-projects/" rel="bookmark" class="crp_title">Slow Actions in Rails Projects</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/11/problems-with-restful_authentication-plugin-and-internet-explorer-cookies/" rel="bookmark" class="crp_title">Problems with restful_authentication Plugin and Internet Explorer Cookies</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/01/22/ubuntu-byobu-landscape/" rel="bookmark" class="crp_title">Using Byobu and Landscape to improve remote Ubuntu sessions</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/" rel="bookmark" class="crp_title">Properly Setting HTTP_REFERER in a Rails Integration Test for a File Upload</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/12/watch-multiple-logs-in-a-single-terminal/" rel="bookmark" class="crp_title">Watch Multiple Logs in a Single Terminal</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/05/04/find-the-unique-sessions-for-a-rails-application/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Reintroducing sanitize_email &#124; Work with Production Email without Fear</title>
		<link>http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 15:27:43 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[ActionMailer]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[QA]]></category>
		<category><![CDATA[email]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=579</guid>
		<description><![CDATA[An issue I have to tackle on almost every project I encounter is developing, QA&#8217;ing, and troubleshooting email generated from my app. Rails provides a couple of options to help during the development and test phases (setting action_mailer.delivery_method = :test), but there aren&#8217;t any great mechanisms for performing QA with a client or troubleshooting production [...]]]></description>
			<content:encoded><![CDATA[<p>An issue I have to tackle on almost every project I encounter is developing, QA&#8217;ing, and troubleshooting email generated from my app.  Rails provides a couple of options to help during the development and test phases (setting action_mailer.delivery_method = :test), but there aren&#8217;t any great mechanisms for performing QA with a client or troubleshooting production email issues (formatting, content, etc).</p>
<p>Not long ago I stumbled upon <a href="http://galtzo.blogspot.com/2008/11/sanitize-email-never-worry-about.html">Peter Boling&#8217;s plugin implementation of sanitize_email</a>.  I&#8217;ve since forked it, turned it into a gem, and continued to apply maintenance commits to it as rails has marched forward through versions 2.2 and 2.3.  </p>
<p>The primary value <a href="http://johntrupiano.rubyforge.org/sanitize_email">sanitize_email</a> provides is that it allows you to reroute all email without having to alter any application code.  It&#8217;s environment-specific and doesn&#8217;t introduce any production/deployment dependencies.</p>
<p><span id="more-579"></span></p>
<h3>Installation</h3>
<p>To install, simply execute:<br />
<code></p>
<pre>
  $> sudo gem install sanitize_email
</pre>
<p></code></p>
<h3>Use Cases</h3>
<p>There are three primary use cases for sanitize_email.</p>
<h4>Working Locally with Production Data</h4>
<p>Scenario: you have a mechanism for recreating your production environment in your development environment (<a href="http://github.com/jtrupiano/capistrano-extensions">capistrano-extensions</a> provides this capability for MySQL databases).  You want to pull down the production data to troubleshoot a live email issue.  Using sanitize_email, we can set up our dev environment to override all email envelopes so that email actually goes to an inbox of your choice.</p>
<h4>Re-routing Email on a Staging or QA Server</h4>
<p>During initial development of a new email feature, it&#8217;s imperative that the client/stakeholder be able to review all emails being generated.  sanitize_email makes it dead simple to specify that your staging environment route all email generated to a specific email address without having to change any application code.</p>
<h4>Testing Email from a Hot Production Server</h4>
<p>You can install sanitize_email on your production server, and then utilize it from the console to give you more freedom when poking and prodding your application.  You can trigger any email you need to without fear that it will go to a real live email address.</p>
<h3>Sample Usage of sanitize_email</h3>
<p>sanitize_email uses ActionMailer::Base.local_environments to specify in which environments to override the SMTP envelope.  Note that a set of defaults can be configured in an initializer file, and then overridden in specific environment files for further control.</p>
<p><code></p>
<pre>
    # Settings for sanitize_email gem.  These can be overridden in individual config/%env%/environment.rb files.
    require 'sanitize_email'
    ActionMailer::Base.sanitized_recipients = "john@smartlogicsolutions.com"
    ActionMailer::Base.sanitized_bcc = nil
    ActionMailer::Base.sanitized_cc = nil

    # These are the environments whose outgoing email BCC, CC and recipients fields will be overridden!
    # All environments not listed will be treated as normal.
    ActionMailer::Base.local_environments = %w( development test staging )
</pre>
<p></code></p>
<h3>Closing Notes</h3>
<p>The functionality provided by sanitize_email is truly very basic, and admittedly a little static.  You can only set a single override for any given environment, which doesn&#8217;t lend itself to a QA/review team that consists of more than a single person.  I have been working on <a href="http://github.com/jtrupiano/rails-caddy">rails-caddy</a> which is a tool for bringing a lot of QA goodness to the browser.  One feature it provides is an integration with sanitize_email, allowing these overridden email addresses to be set on a per session basis, which in turn allows several individuals to work on a staging server at the same time and each receive the email that their own actions triggered.  It&#8217;s still in its early stages (pre 0.1.0 release), but it&#8217;s something we&#8217;re using on several apps already.</p>
<h3>Related Links</h3>
<p><a href="http://johntrupiano.rubyforge.org/sanitize_email">RDoc</a> | <a href="http://github.com/jtrupiano/sanitize_email">Source on GitHub</a></p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/04/30/using-sanitize-email-to-preview-html-emails-locally/" rel="bookmark" class="crp_title">Using Sanitize Email to Preview HTML Emails Locally</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/02/better-setup-for-environments-in-rails/" rel="bookmark" class="crp_title">Better setup for environments in Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/08/04/introducing-environmentalize-an-intuitive-environment-focused-config-structure-for-your-rails-applications/" rel="bookmark" class="crp_title">Introducing environmentalist: an intuitive, environment-focused config structure for your rails applications</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/04/environmentalist-023-released-supports-rails-232/" rel="bookmark" class="crp_title">environmentalist 0.2.3 released &#8212; supports rails 2.3.2</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/" rel="bookmark" class="crp_title">Rails 2.3 Nested Object Forms: I&#8217;m not Crazy about Them</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>environmentalist 0.2.3 released &#8212; supports rails 2.3.2</title>
		<link>http://blog.smartlogicsolutions.com/2009/04/04/environmentalist-023-released-supports-rails-232/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/04/04/environmentalist-023-released-supports-rails-232/#comments</comments>
		<pubDate>Sat, 04 Apr 2009 19:56:44 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[Configuration]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Add new tag]]></category>
		<category><![CDATA[environmentalist]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[release]]></category>
		<category><![CDATA[rubygem]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=574</guid>
		<description><![CDATA[Just a heads up that I&#8217;ve released environmentalist 0.2.3. You can update with: sudo gem install environmentalist The only substantial change in this release is that we moved the loading of postboot.rb to the bottom of the boot.rb file as opposed to the top of config/environment.rb. This was necessary because common db rake tasks like [...]]]></description>
			<content:encoded><![CDATA[<p>Just a heads up that I&#8217;ve released <a href="http://johntrupiano.rubyforge.org/environmentalist/">environmentalist</a> 0.2.3.  You can update with:</p>
<pre><code>
  sudo gem install environmentalist
</code></pre>
<p>The only substantial change in this release is that we moved the loading of postboot.rb to the bottom of the boot.rb file as opposed to the top of config/environment.rb.  This was necessary because common db rake tasks like db:create and db:drop stopped loading the environment in 2.3.2.</p>
<p>As a recap, environmentalist provides an executable that converts a rails app&#8217;s config structure.  The basic idea is that environments themselves are now first-class citizens, allowing you to create several environments (e.g. staging, prodtest, demo, etc.) in a clean, organized fashion.  Each environment is given its own folder where it can store its own set of configuration files (think mongrel configs, apache configs, etc.) without polluting the top-level config/ directory.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/08/04/introducing-environmentalize-an-intuitive-environment-focused-config-structure-for-your-rails-applications/" rel="bookmark" class="crp_title">Introducing environmentalist: an intuitive, environment-focused config structure for your rails applications</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/02/better-setup-for-environments-in-rails/" rel="bookmark" class="crp_title">Better setup for environments in Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/" rel="bookmark" class="crp_title">Reintroducing sanitize_email | Work with Production Email without Fear</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/06/deploying-rails-apps-with-capistrano-without-root-or-sudo-privileges/" rel="bookmark" class="crp_title">Deploying Rails Apps with Capistrano without root or sudo Privileges</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/04/04/environmentalist-023-released-supports-rails-232/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails 2.3 Nested Object Forms: I&#8217;m not Crazy about Them</title>
		<link>http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/#comments</comments>
		<pubDate>Tue, 24 Feb 2009 15:00:51 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[ActionPack]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[accepts_nested_attributes_for]]></category>
		<category><![CDATA[nested object forms]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails2.3]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=529</guid>
		<description><![CDATA[I&#8217;m a couple of weeks late, but I just finished reviewing Rails 2.3 Nested Object Forms. While a very nice and &#8220;magical&#8221; feature, I&#8217;ve got to admit that I&#8217;m really not that crazy about how it works. Let me be the first to admit that there&#8217;s no one right way to do things. In fact, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a couple of weeks late, but I just finished reviewing <a href="http://ryandaigle.com/articles/2009/2/1/what-s-new-in-edge-rails-nested-attributes">Rails 2.3 Nested Object Forms</a>.  While a very nice and &#8220;magical&#8221; feature, I&#8217;ve got to admit that I&#8217;m really not that crazy about how it works.</p>
<p>Let me be the first to admit that there&#8217;s no one right way to do things.  In fact, I&#8217;m writing this post particularly because I have a few objections to how this functionality is ultimately exposed, and I&#8217;d like to hear arguments from those who disagree.  In other words, let me acknowledge the possibility that I am the misguided one.</p>
<p><span id="more-529"></span></p>
<h3>Review of Nested Object Forms</h3>
<p>As a quick review, we can now prepare our models for nested object mass assignment:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:name</span>
&nbsp;
  has_many <span style="color:#ff3333; font-weight:bold;">:children</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:children</span>
    <span style="color:#008000; font-style:italic;"># can also be used on has_one etc.. associations</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Child <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>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>We specify which nested relationships can be passed in via mass assignment using the <code>accepts_nested_attributes_for()</code> function.  Continuing the example, we can now execute the following to actually save a person and two children at the same time:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">person = Person.<span style="color:#9900CC;">create</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'George'</span>, <span style="color:#ff3333; font-weight:bold;">:children_attributes</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#996600;">&quot;new_1&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Amy'</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#996600;">&quot;new_2&quot;</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Stephanie'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>For full disclosure, my console session from start to finish:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">john-mbp:playground john$ rails <span style="color: #660033;">-v</span>
Rails 2.3.0
john-mbp:playground john$ rails anewapp
...
...
john-mbp:playground john$ <span style="color: #7a0874; font-weight: bold;">cd</span> anewapp<span style="color: #000000; font-weight: bold;">/</span>
john-mbp:anewapp john$ ruby script<span style="color: #000000; font-weight: bold;">/</span>generate model person name:string
...
john-mbp:anewapp john$ ruby script<span style="color: #000000; font-weight: bold;">/</span>generate model child name:string person_id:integer
...
&nbsp;
<span style="color: #666666; font-style: italic;"># edit app/models/person.rb as above</span>
<span style="color: #666666; font-style: italic;"># edit app/models.child.rb as above</span>
&nbsp;
john-mbp:anewapp john$ rake db:migrate
<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #000000; font-weight: bold;">in</span> <span style="color: #000000; font-weight: bold;">/</span>Users<span style="color: #000000; font-weight: bold;">/</span>john<span style="color: #000000; font-weight: bold;">/</span>playground<span style="color: #000000; font-weight: bold;">/</span>anewapp<span style="color: #7a0874; font-weight: bold;">&#41;</span>
==  CreatePeople: migrating ===================================================
<span style="color: #660033;">--</span> create_table<span style="color: #7a0874; font-weight: bold;">&#40;</span>:people<span style="color: #7a0874; font-weight: bold;">&#41;</span>
   -<span style="color: #000000; font-weight: bold;">&gt;</span> 0.0044s
==  CreatePeople: migrated <span style="color: #7a0874; font-weight: bold;">&#40;</span>0.0046s<span style="color: #7a0874; font-weight: bold;">&#41;</span> ==========================================
&nbsp;
==  CreateChildren: migrating =================================================
<span style="color: #660033;">--</span> create_table<span style="color: #7a0874; font-weight: bold;">&#40;</span>:children<span style="color: #7a0874; font-weight: bold;">&#41;</span>
   -<span style="color: #000000; font-weight: bold;">&gt;</span> 0.0041s
==  CreateChildren: migrated <span style="color: #7a0874; font-weight: bold;">&#40;</span>0.0045s<span style="color: #7a0874; font-weight: bold;">&#41;</span> ========================================
&nbsp;
john-mbp:anewapp john$ ruby script<span style="color: #000000; font-weight: bold;">/</span>console 
Loading development environment <span style="color: #7a0874; font-weight: bold;">&#40;</span>Rails 2.3.0<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> person = Person.create<span style="color: #000000; font-weight: bold;">!</span><span style="color: #7a0874; font-weight: bold;">&#40;</span>:name =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'George'</span>, :children_attributes =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span><span style="color: #ff0000;">&quot;new_1&quot;</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>:name =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'Amy'</span><span style="color: #7a0874; font-weight: bold;">&#125;</span>, <span style="color: #ff0000;">&quot;new_2&quot;</span> =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>:name =<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #ff0000;">'Stephanie'</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#125;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #666666; font-style: italic;">#&lt;Person id: 1, name: &quot;George&quot;, created_at: &quot;2009-02-24 00:49:21&quot;, updated_at: &quot;2009-02-24 00:49:21&quot;&gt;</span>
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> person.children
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #666666; font-style: italic;">#&lt;Child id: 1, name: &quot;Amy&quot;, person_id: 1, created_at: &quot;2009-02-24 00:49:21&quot;, updated_at: &quot;2009-02-24 00:49:21&quot;&gt;, #&lt;Child id: 2, name: &quot;Stephanie&quot;, person_id: 1, created_at: &quot;2009-02-24 00:49:21&quot;, updated_at: &quot;2009-02-24 00:49:21&quot;&gt;]</span>
<span style="color: #000000; font-weight: bold;">&gt;&gt;</span> person.children.size
=<span style="color: #000000; font-weight: bold;">&gt;</span> <span style="color: #000000;">2</span></pre></div></div>

<p>Pretty cool, huh?  I agree.  I think this is fantastic, and with the integration with fields_for, it will really ease a lot of the pain that previously existed with multi-model forms.</p>
<p>This said, I&#8217;ve got a few major bones to pick with how it&#8217;s implemented.</p>
<h3>So What&#8217;s Wrong?</h3>
<p>The primary issue is the fact that this functionality is statically defined (in that you can&#8217;t turn it on/off in specific scenarios).  Why is this an issue?  Well, this is a potentially dangerous functionality to expose everywhere.  Let&#8217;s say that you wanted to take advantage of this new feature to allow administrators to create new accounts that came pre-loaded with a complementary $X credit to their accounts.  So you built a form for admins to fill out that included a <code>fields_for :credits</code> to achieve this single-form implementation of an account with credits.  Now, in order to avail of this, I need to turn on the nested mass assignment.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:credits</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:credits</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Credit <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>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Wait&#8230;.I&#8217;ve just turned this feature on globally&#8230;..I can&#8217;t just make it available at the controller level?  But isn&#8217;t the controller where I define authorization, who can edit/update/create what?  Precisely.  </p>
<p>So&#8230;.unless I want to go old school and rewrite this all by hand, anytime I want to render a person form (e.g. on an &#8220;Edit My Profile&#8221; link for authenticated users), I need to recall that I&#8217;ve exposed myself to a possible POST data hack (anyone who understands this feature in rails will know how to handcraft the POST data).  This is a fairly ridiculous thing to expect on a project of any nontrivial size.</p>
<p>However, there&#8217;s another way around this issue.  Rather than rewriting all of the multi-model form stuff by hand, I could simply ward off the extra parameters at the controller level, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> ProfileController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  before_filter <span style="color:#ff3333; font-weight:bold;">:remove_nested_params</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> update
    <span style="color:#0066ff; font-weight:bold;">@user</span> = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>current_user.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@user</span>.<span style="color:#9900CC;">update_attributes</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>params<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:#006600; font-weight:bold;">&#41;</span>
    redirect_to profile_path
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'edit'</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  protected
    <span style="color:#9966CC; font-weight:bold;">def</span> remove_nested_params
      params<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:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:credits</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></pre></div></div>

<p>This works fine in isolation or for a one-off, but again, this is a piece of information that is going to be lost as the project trudges along.  Your team will forget this, and someone is going to forget to &#8220;close the hole&#8221; when adding that new &#8220;quick edit profile&#8221; form that only shows their email address and display name.</p>
<h3>Counter Suggestions</h3>
<p>I would advocate any solution where this behavior was pushed out to controllers.  That said, I don&#8217;t have an airtight procedure planned out.  I will, however, leave you with a few suggestions.</p>
<p>We could implement it around_filter style where the feature is enabled/disabled in an around_filter.  The primary benefit of this approach would be that the majority of the code could probably stay put in ActiveRecord.  We&#8217;d just need to expose hooks to turn it on/off.  Then we could define a controller-level meta-function (e.g. filter_parameter_logging) that could set which actions to apply the behavior on, or which models can be nested.  The syntax could look 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> ProfileController <span style="color:#006600; font-weight:bold;">&lt;</span> ApplicationController
  allow_nested_assignment_for User, <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:children</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:update</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I&#8217;ll be perfectly honest in that I don&#8217;t love this suggestion.  It incorrectly scopes this authorization tweak to the whole action and any before/after filters that execute in between it (still leaving holes, albeit smaller) as opposed to scoping it directly to the single save! action that we really want to special-case.  If we perhaps exposed a separate save_with_nested() function, then we could isolate the scope down to the specific call.  Needless to say, I doubt this is a course of action rails would take, and it&#8217;s not one I would advocate.</p>
<p>Another alternative would be to keep the functionality as is, but then allow you to override or extend it at the controller level (a la my initial suggestion).  This would allow developers to avail of the benefits in the less-risky areas, and then conditionally avail of them in more risky areas by simply turning it on for specific controller/action combos.  In this case, we&#8217;d define a basic harmless nested assignment baseline in the model, and the more risky nested assignment in those controllers where we wanted to isolate it, e.g.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:children</span>
  has_many <span style="color:#ff3333; font-weight:bold;">:credits</span>
  accepts_nested_attributes_for <span style="color:#ff3333; font-weight:bold;">:children</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#6666ff; font-weight:bold;">Admin::PeopleController</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  allow_nested_assignment_for User, <span style="color:#ff3333; font-weight:bold;">:credits</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:create</span>, <span style="color:#ff3333; font-weight:bold;">:update</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The primary benefit of an approach like this is that it aligns properly to a developer&#8217;s train of thought.  When you go to add a trivial feature, you don&#8217;t think &#8220;I need to close that gap my unrelated nontrivial feature added for me.&#8221;  However, when you go to add a nontrival feature (like allowing an admin to auto-create credits in their new account form), you do think &#8220;what do I need to differently?&#8221;  In the former case, the developer thinks his new feature is trivial, and doesn&#8217;t expect to have do anything exceptional for it.  In the latter case, the developer thinks his new feature is nontrivial, and will think about it from a &#8220;what extra work does that mean for me?&#8221; standpoint.</p>
<h3>Closing Thoughts</h3>
<p>One of the biggest things that worries me is that no one is talking about this.  The whole community <a href="http://rails.uservoice.com/pages/rails3">requested this feature</a>, and at this point it has received quite a bit of fanfare.  But there are some clear ways to accidentally screw yourself that just aren&#8217;t being mentioned as caveats.</p>
<p>To be entirely blunt, I just feel like this is plugin material at this point.  Though I commend rails for opening up its feature set to a community vote, I fear that we may have misstepped with this feature in particular.  I&#8217;m very curious to hear what others think.  (Be gentle with the flame)</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/" rel="bookmark" class="crp_title">Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/25/reintroducing-sanitize_email-work-with-production-email-without-fear/" rel="bookmark" class="crp_title">Reintroducing sanitize_email | Work with Production Email without Fear</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/23/dont-abuse-the-session/" rel="bookmark" class="crp_title">Don&#8217;t Abuse the Session</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/" rel="bookmark" class="crp_title">Timecop: Freeze Time in Ruby for Better Testing</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/05/mapresources-and-custom-nested-routes/" rel="bookmark" class="crp_title">map.resources and custom nested routes</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>AASM + interning empty string error</title>
		<link>http://blog.smartlogicsolutions.com/2009/02/13/aasm-interning-empty-string-error/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/02/13/aasm-interning-empty-string-error/#comments</comments>
		<pubDate>Fri, 13 Feb 2009 22:06:29 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[AASM]]></category>
		<category><![CDATA[error]]></category>
		<category><![CDATA[interning]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[rails2.1.2]]></category>
		<category><![CDATA[rubyist]]></category>
		<category><![CDATA[rubyist-aasm2.0.5]]></category>
		<category><![CDATA[string]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=507</guid>
		<description><![CDATA[Second time I&#8217;ve run into this in the past week, so I thought I&#8217;d share it with you guys. I fumbled for a short while with the extremely unhelpful error message &#8220;interning empty string error&#8221; after a re-deployment to my staging server. It seemed to be affecting all of my pages, and I couldn&#8217;t really [...]]]></description>
			<content:encoded><![CDATA[<p>Second time I&#8217;ve run into this in the past week, so I thought I&#8217;d share it with you guys.  I fumbled for a short while with the extremely unhelpful error message &#8220;interning empty string error&#8221; after a re-deployment to my staging server.  It seemed to be affecting all of my pages, and I couldn&#8217;t really load any page.</p>
<h3>The Problem</h3>
<div style="margin-top: 10px; padding: 4px; border: solid 1px black; background-color: #e0e0e0">This blog post is valid for rails 2.1.2 and rubyist-aasm 2.0.5.  It may apply to other version combinations, but I make no guarantees.</div>
<p>First, let&#8217;s dive into the error itself.  This error message occurs when you call to_sym on an empty string:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">john<span style="color:#006600; font-weight:bold;">-</span>mbp:trunk john$ irb
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#996600;">&quot;&quot;</span>.<span style="color:#9900CC;">to_sym</span>
<span style="color:#CC00FF; font-weight:bold;">ArgumentError</span>: interning empty <span style="color:#CC0066; font-weight:bold;">string</span>
	from <span style="color:#006600; font-weight:bold;">&#40;</span>irb<span style="color:#006600; font-weight:bold;">&#41;</span>:<span style="color:#006666;">1</span>:<span style="color:#9966CC; font-weight:bold;">in</span> <span style="color:#996600;">`to_sym'
	from (irb):1</span></pre></div></div>

<p>Now that we know what&#8217;s up, let&#8217;s dig into my stack trace.  </p>
<div style="width: 500px;">
   /opt/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rubyist-aasm-2.0.5/lib/persistence/active_record_persistence.rb:233:in `to_sym&#8217;<br />
   /opt/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rubyist-aasm-2.0.5/lib/persistence/active_record_persistence.rb:233:in `aasm_read_state&#8217;<br />
   /opt/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rubyist-aasm-2.0.5/lib/persistence/active_record_persistence.rb:135:in `aasm_current_state&#8217;<br />
   /opt/ruby-enterprise-1.8.6-20090113/lib/ruby/gems/1.8/gems/rubyist-aasm-2.0.5/lib/aasm.rb:50:in `disabled?&#8217;<br />
   /var/vhosts/discovered/releases/20090213213806/app/helpers/base_admin_helper.rb:4:in `disable_link&#8217;<br />
   /var/vhosts/discovered/releases/20090213213806/app/views/schools/index.rhtml:16:in `_run_erb_47app47views47schools47index46rhtml&#8217;<br />
   /var/vhosts/discovered/releases/20090213213806/app/views/schools/index.rhtml:12:in `each&#8217;<br />
   /var/vhosts/discovered/releases/20090213213806/app/views/schools/index.rhtml:12:in `_run_erb_47app47views47schools47index46rhtml&#8217;<br />
&#8230;<br />
&#8230;<br />
&#8230;
</div>
<p>The cause of this bug is the fact that my newest build added an aasm_state column to the School model, but my migration did not properly default schools to a particular state.  As such, when an instance of the model was asked for its state, the AASM codebase raised an error.  And this occurred on every page because I was rendering a link to a school in a common layout.</p>
<h3>The Solution</h3>
<p>After the fact, in SQL:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">UPDATE</span> schools <span style="color: #993333; font-weight: bold;">SET</span> aasm_state <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'active'</span>;</pre></div></div>

<p>Or better yet, before the fact, in my migration:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
  add_column <span style="color:#ff3333; font-weight:bold;">:schools</span>, <span style="color:#ff3333; font-weight:bold;">:aasm_state</span>, :<span style="color:#CC0066; font-weight:bold;">string</span>
  School.<span style="color:#9900CC;">reset_column_information</span>
  School.<span style="color:#9900CC;">update_all</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;aasm_state&quot;</span>, <span style="color:#996600;">&quot;active&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<h3>The Lesson</h3>
<p>Don&#8217;t forget that there&#8217;s a difference between a migration for a yet-to-be-deployed application and a live running application.  Live apps require you to take into account that data already exists.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/06/03/error-in-will_paginate-gem-running-rails-210/" rel="bookmark" class="crp_title">Error in will_paginate gem running Rails 2.1.0</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/09/04/ruby-patch-to-fix-broken-yamldump-for-multi-line-strings-stringto_yaml/" rel="bookmark" class="crp_title">Ruby: Patch to fix broken YAML.dump for multi-line strings (String#to_yaml)</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/04/26/integrity-ci-on-passenger-222-with-ruby-enterprise-edition-on-ubuntu-804/" rel="bookmark" class="crp_title">Integrity CI on Passenger 2.2.2 with Ruby Enterprise Edition on Ubuntu 8.04</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/05/13/directory-conventions-for-rack-middleware-rubygems/" rel="bookmark" class="crp_title">Directory Conventions for Rack Middleware RubyGems</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/01/14/aptinstaller-032-released/" rel="bookmark" class="crp_title">Aptinstaller 0.3.2 Released</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/02/13/aasm-interning-empty-string-error/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Properly Setting HTTP_REFERER in a Rails Integration Test for a File Upload</title>
		<link>http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/</link>
		<comments>http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/#comments</comments>
		<pubDate>Wed, 04 Feb 2009 00:38:01 +0000</pubDate>
		<dc:creator>Greg Jastrab</dc:creator>
				<category><![CDATA[Greg Jastrab]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[file upload]]></category>
		<category><![CDATA[integration]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=495</guid>
		<description><![CDATA[This one had me frustrated for the past hour. I&#8217;ve been writing integration tests for a Rails project and got stuck on an error when I was trying to test that a file upload worked successfully and asserted a redirection was occuring correctly, but ran into the following error: Expected response to be a &#60;:redirect&#62;, [...]]]></description>
			<content:encoded><![CDATA[<p>This one had me frustrated for the past hour.  I&#8217;ve been writing integration tests for a Rails project and got stuck on an error when I was trying to test that a file upload worked successfully and asserted a redirection was occuring correctly, but ran into the following error:</p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Expected response to be a <span style="color:#006600; font-weight:bold;">&lt;</span>:redirect<span style="color:#006600; font-weight:bold;">&gt;</span>, but was <span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#006666;">500</span><span style="color:#006600; font-weight:bold;">&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;</span><span style="color:#996600;">&quot;No HTTP_REFERER was set in the request to this action, so
redirect_to :back could not be called successfully. If this
is a test, make sure to specify
request.env[<span style="color:#000099;">\&quot;</span>HTTP_REFERER<span style="color:#000099;">\&quot;</span>].&quot;</span><span style="color:#006600; font-weight:bold;">&gt;</span></pre></div></div>

<p>What a lovely error message to send me on a goose chase trying to set HTTP_REFERER directly on the @request as instructed.</p>
<h4>Did Not Work</h4>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#0066ff; font-weight:bold;">@request</span>.<span style="color:#9900CC;">env</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;HTTP_REFERER&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">'/'</span>
post upload_path, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:file</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fixture_file_upload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;worddoc.docx&quot;</span>, <span style="color:#996600;">&quot;application/msword&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:html</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:multipart <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
assert_redirected_to <span style="color:#996600;">'/'</span>, <span style="color:#996600;">'index'</span></pre></div></div>

<p>This continued to spit out the same error.  I finally stumbled across <a href="http://redsquirrel.com/cgi-bin/dave/2006/08/index.html">a post back from 2006</a> that held the answer.  The HTTP_REFERER is not set the same way in an integration test:</p>
<h4>Success!</h4>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">post upload_path, <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:file</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fixture_file_upload<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;worddoc.docx&quot;</span>, <span style="color:#996600;">&quot;application/msword&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:html</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:multipart <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#125;</span>, <span style="color:#ff3333; font-weight:bold;">:referer</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'/'</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
assert_redirected_to <span style="color:#996600;">'/'</span>, <span style="color:#996600;">'index'</span></pre></div></div>

<p>Hope that saves anyone else some time if you encounter this error.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2007/06/12/struts-11-problems-with-logiciterate-tags-and-cannot-find-bean-xxx-under-any-scope/" rel="bookmark" class="crp_title">Struts 1.1: Problems with logic:iterate tags and &#8220;Cannot find bean XXX under any scope&#8221;</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/08/08/using-active-x-and-javascript-to-scan-from-your-web-app/" rel="bookmark" class="crp_title">using active x and javascript to scan from your web app</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/23/dont-abuse-the-session/" rel="bookmark" class="crp_title">Don&#8217;t Abuse the Session</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/10/26/testpilot-rails-integration-testing-pattern/" rel="bookmark" class="crp_title">TestPilot &#8211; Rails Integration Testing Pattern</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/15/automating-flex-compilation-using-ant/" rel="bookmark" class="crp_title">Automating Flex Compilation Using ANT</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2009/02/03/properly-setting-http_referer-in-a-rails-integration-test-to-upload-file/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Timecop: Freeze Time in Ruby for Better Testing</title>
		<link>http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/#comments</comments>
		<pubDate>Wed, 19 Nov 2008 15:07:44 +0000</pubDate>
		<dc:creator>John Trupiano</dc:creator>
				<category><![CDATA[John Trupiano]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Testing]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[tatft]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[timecop]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=360</guid>
		<description><![CDATA[The API mentioned in this blog post is specific to v0.1.0. The latest version is v0.2.0. See the blog post announcement, the documentation, or the github home page. This past weekend I released v0.1.0 of the Timecop gem. Timecop makes it dead simple to travel through or freeze time for the sake of creating a [...]]]></description>
			<content:encoded><![CDATA[<div style="background-color: #e0e0e0; border-color: #999999; padding: 6px;">
The API mentioned in this blog post is specific to v0.1.0.  The latest version is v0.2.0.  See the <a href="http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/">blog post announcement</a>, the <a href="http://johntrupiano.rubyforge.org/timecop">documentation</a>, or the <a href="http://github.com/jtrupiano/timecop">github home page</a>.
</div>
<p>This past weekend I released v0.1.0 of the <a href="http://github.com/jtrupiano/timecop">Timecop</a> gem.  Timecop makes it dead simple to travel through or freeze time for the sake of creating a predictable and ultimately testable scenario.</p>
<p>The gem is derived from a plugin I wrote a while back to achieve more or less the same functionality for an extremely time-sensitive application.  My goals for the gem included:</p>
<ol>
<li><strong>Drop-in-ability</strong>: The primary goal is to allow your app to continue to use Time.now, Date.today and DateTime.now as normal within your application.  No overloading of functions with optional arguments (a la today=Date.today) just so you can write test cases.</li>
<li><strong>Environment independence</strong>: I wanted the gem to work (a) w/ rails (ActiveSupport actually), (b) w/ plain ruby when the &#8216;date&#8217; library has been loaded, and (c) w/ plain ruby when the &#8216;date&#8217; library had not been loaded.</li>
<li><strong>Library independence</strong>: I could have utilized mocha to achieve the mocking functionality found under the hood, but because I wanted this to work with plain vanilla ruby, libraries like mocha are out.</li>
<li><strong>Short-term time travel</strong>: I wanted to expose the ability to temporarily change the concept of &#8220;now.&#8221;  This is particularly helpful when writing tests where time needs to pass.</li>
<li><strong>Long-range time travel</strong>: I wanted to expose the ability to change the concept of &#8220;now&#8221; for an indeterminate period of time.  This is particularly helpful when setting up a rails test environment along with the test data.</li>
<li><strong>Nested time travel</strong>: I wanted to provide the ability to nest traveling, allowing the state to be kept within each block (we&#8217;ll see an example later).</li>
</ol>
<p>The gem is hosted on RubyForge and can be installed by simply running:</p>
<pre>sudo gem install timecop</pre>
<p><span id="more-360"></span></p>
<h2>Using Timecop</h2>
<p>The most basic example is to utilize this within a test.  Consider the following test case:</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;">'timecop'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'test/unit'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> MyTestCase <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span></span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_mortgage_due_in_30_days
    john = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    john.<span style="color:#9900CC;">sign_mortgage</span>!
    assert !john.<span style="color:#9900CC;">mortgage_payment_due</span>?
    Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#006666;">30</span>.<span style="color:#9900CC;">days</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      assert john.<span style="color:#9900CC;">mortgage_payment_due</span>?
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>What&#8217;s nice about this API is that the #travel function will take several different object types.  You can pass a Time instance, a Date instance, a DateTime instance, or individual time parameters (the same arguments Time.local()) takes.  Also, if you&#8217;re a big fan of the <a href="http://chronic.rubyforge.org/">chronic</a> gem, then you can easily combine these two:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span>Chronic.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'this tuesday 5:00'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  <span style="color:#008000; font-style:italic;"># test-fu</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>For some applications, you may find it useful to completely re-base the concept of &#8220;now&#8221; for your test environment.  Whenever time-sensitivity is a major priority for your application (e.g. an ordering and delivery system, or any system that encapsulates the concept of &#8220;availability&#8221; at a particularly fine-grained level) , you may find it useful to &#8220;root&#8221; your test data at a particular point in time, allowing you to write very specific tests that don&#8217;t fall victim to the unstoppable march of real time.</p>
<p>To achieve a static date for your entire test environment, you can simply drop the following into config/environments/test.rb (or config/test/environment.rb if you use <a href="http://github.com/jtrupiano/environmentalist">environmentalist</a>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># Setting &quot;now&quot; to May 15, 2008 10:00:00 AM</span>
Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">5</span>, <span style="color:#006666;">15</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">0</span>, <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>This will cause your whole application to run at a static time.  As mentioned previously, this is particularly important for creating static test cases.  You may think that you can achieve this by always using relative times, but this proves much more difficult than initially perceived.  For example, let&#8217;s consider the following scenario, which is an extension of the mortgage example beforehand.  Let&#8217;s say the business rule is that a mortgage payment is due every month on the same date as the lease is signed, except for when that day falls on a weekend, in which case the payment would be due the following Monday.  As such, it&#8217;s extremely crucial for us to write a test case where we know the date in the next month falls on a weekend, and a separate test case where the date in the next month falls on a weekday.  As such, there are certain months where the following test (not using Timecop) would fail:</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;">'test/unit'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> MyTestCase <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#CC00FF; font-weight:bold;"><span style="color:#6666ff; font-weight:bold;">Test::Unit::TestCase</span></span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_mortgage_due_in_30_days
    john = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    john.<span style="color:#9900CC;">sign_mortgage</span>!
    assert !john.<span style="color:#9900CC;">mortgage_payment_due</span>?
    assert john.<span style="color:#9900CC;">mortgage_payment_due</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>Chronic.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;1 month from now&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</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></pre></div></div>

<p>Furthermore, you&#8217;ll notice I had to pass a date to the mortgage_payment_due? function, essentially requiring me to change the signature of that function to take an optional date argument.  Basically, in order to test my application, I&#8217;ve had to go ahead and change my actual code!  Something clearly smells here.  Another option would be to use mocha to mock Time.now.  However, mocha has its own limitations with its inability to unmock.  Lastly, specifically mocking Time.now would leave us high and dry if our implementation decided to start using DateTime.now for comparison in lieu of Time.now.</p>
<p>Another feature that I want to illustrate is the ability to nest #travel commands.  The following assertions will all pass:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">   <span style="color:#008000; font-style:italic;"># this test is taken directly from the test/test_timecop.rb</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_recursive_travel
    t = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> 
      assert_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      t2 = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span>, <span style="color:#006666;">9</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        assert_equal t2, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      assert_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    assert_nil <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:mock_time</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Lastly, Timecop handles the scenario where exceptions are raised within the blocks passed to the #travel function.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># this test is taken directly from the test/test_timecop.rb</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> test_exception_thrown_in_travel_block_properly_resets_time
    t = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">local</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">2008</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span>, <span style="color:#006666;">10</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
      Timecop.<span style="color:#9900CC;">travel</span><span style="color:#006600; font-weight:bold;">&#40;</span>t<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
        assert_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
        <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#996600;">&quot;blah exception&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">rescue</span>
      assert_not_equal t, <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
      assert_nil <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:mock_time</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></pre></div></div>

<p>Timecop is useful both in small and large consumption.  Just as mocha can be helpful to give you a quick mock here and there, Timecop can help guide you very easily through testing the few time-sensitive parts of your application.  And for those unique applications where everything is time-sensitive, Timecop gives you a very simple way to stabilize your concept of now.</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2009/09/20/timecop-0-3-0-released/" rel="bookmark" class="crp_title">Timecop 0.3.0 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/12/07/timecop-0-3-4-released/" rel="bookmark" class="crp_title">Timecop 0.3.4 Released</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/12/24/timecop-2-released-freeze-and-rebase-time-ruby/" rel="bookmark" class="crp_title">Timecop 0.2.0 Released: Freeze and Rebase Time in Ruby</a></li><li><a href="http://blog.smartlogicsolutions.com/2010/10/08/testing-ajax-with-testunit/" rel="bookmark" class="crp_title">Testing AJAX with Test::Unit</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/07/i-cant-upgrade-rubygems-from-111-to-120-on-ubuntu/" rel="bookmark" class="crp_title">I can&#8217;t upgrade RubyGems from 1.1.1 to 1.2.0 on Ubuntu</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/11/19/timecop-freeze-time-in-ruby-for-better-testing/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Using ActiveRecord&#8217;s to_xml to produce custom xml including deep level associations</title>
		<link>http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/</link>
		<comments>http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/#comments</comments>
		<pubDate>Wed, 10 Sep 2008 18:49:34 +0000</pubDate>
		<dc:creator>Glenn Gentzke</dc:creator>
				<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Glenn Gentzke]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[XML]]></category>
		<category><![CDATA[deep level associations]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[to_xml]]></category>

		<guid isPermaLink="false">http://blog.smartlogicsolutions.com/?p=237</guid>
		<description><![CDATA[ActiveRecord provides a powerful method to all its records called to_xml. Most web developers using RoR should be familiar with its usage and hopefully use it for their simple xml production needs. But what do you do when you need to produce xml that is selective, includes associations, or contains custom tags? There are many [...]]]></description>
			<content:encoded><![CDATA[<p>ActiveRecord provides a powerful method to all its records called <strong>to_xml</strong>.  Most web developers using RoR should be familiar with its usage and hopefully use it for their simple xml production needs.  But what do you do when you need to produce xml that is selective, includes associations, or contains custom tags?  There are many ways to manipulate to_xml&#8217;s output and I&#8217;ll explain a few below.<br />
<span id="more-237"></span></p>
<h3>The Options Hash</h3>
<p>The most obvious way to change the output is to use the options hash <a href="http://api.rubyonrails.org/classes/ActiveRecord/XmlSerialization.html">outlined in the docs</a>.  A short list of options you might want to explore is:</p>
<ul>
<li>except => [:attr1, :attr2] &#8212; excludes attributes in array from output</li>
<li>only => [:attr1, :attr2] &#8212; output contains only the specified attributes</li>
<li>include	 => [:assoc1, :assoc2] &#8212; calls to_xml on the given first level association and nests it in the output</li>
<li>methods => [:meth1, :meth2] &#8212; adds a tag to output in the format <em>&lt;method-name&gt;[method output]&lt;/method-name&gt;</em></li>
</ul>
<p>Usage is incredibly simple:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># grab xml for a record and its child</span>
  my_record.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span>:<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:child</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># same, but only output the ids and names (assuming both have these attributes)</span>
  my_record.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:only</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:name</span><span style="color:#006600; font-weight:bold;">&#93;</span>, :<span style="color:#9966CC; font-weight:bold;">include</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:child</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<h3>Behold, the Builder</h3>
<p>A fantastic feature of to_xml that <a href="http://ryandaigle.com/articles/2007/4/13/what-s-new-in-edge-rails-a-more-flexible-to_xml">Ryan blogged about last year</a> is that it yields the builder, thus allowing you to add arbitrary tags into the output.  What&#8217;s more is you can pass the builder into another object&#8217;s to_xml method inside the outer block and produced nested xml.</p>
<p>For example:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#008000; font-style:italic;"># Arbitrarily insert a tag</span>
  my_record.<span style="color:#9900CC;">to_xml</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
    xml.<span style="color:#9900CC;">some_tag</span> some_value   <span style="color:#008000; font-style:italic;">#=&gt; &lt;some_tag&gt;some_value&lt;/some_tag&gt;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># I want to get xml for my record and all its children</span>
  my_record.<span style="color:#9900CC;">to_xml</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
    my_record.<span style="color:#9900CC;">children</span>.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>child<span style="color:#006600; font-weight:bold;">|</span> child.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</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></pre></div></div>

<p>You can nest as deep as you want without overriding a model&#8217;s own to_xml method:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  output = my_record.<span style="color:#9900CC;">to_xml</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
    my_record.<span style="color:#9900CC;">children</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>child<span style="color:#006600; font-weight:bold;">|</span>
      child.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>fxml<span style="color:#006600; font-weight:bold;">|</span>
        child.<span style="color:#9900CC;">grandchild</span>.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> fxml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</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></pre></div></div>

<h3>deep_xml: Model methods that utilize (but do not overwrite) to_xml</h3>
<p>I chose to write methods in the models that handled including the children&#8217;s xml such that a single call to my_record.full_xml would produce nested xml automatically.  Notice how the builder is being passed to the children, it&#8217;s important!</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  <span style="color:#9966CC; font-weight:bold;">class</span> ParentClass <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
    has_many <span style="color:#ff3333; font-weight:bold;">:children</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> deep_xml<span style="color:#006600; font-weight:bold;">&#40;</span>builder=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      to_xml<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> builder<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
        children.<span style="color:#9900CC;">each</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>child<span style="color:#006600; font-weight:bold;">|</span> child.<span style="color:#9900CC;">deep_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span>xml<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>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> Child <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;">:parent</span>
    has_one <span style="color:#ff3333; font-weight:bold;">:grandchild</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">def</span> deep_xml<span style="color:#006600; font-weight:bold;">&#40;</span>builder=<span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      to_xml<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> builder, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>xml<span style="color:#006600; font-weight:bold;">|</span>
        grandchild.<span style="color:#9900CC;">to_xml</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:builder</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> xml, <span style="color:#ff3333; font-weight:bold;">:skip_instruct</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</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>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> Grandchild <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;">:child</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># Now the call is simple:</span>
Parent.<span style="color:#9900CC;">firstdeep_xml</span> <span style="color:#008000; font-style:italic;">#=&gt; custom xml for a parent that includes its </span>
                        <span style="color:#008000; font-style:italic;">#   children and their grandchildren (1 each in this case)</span></pre></div></div>

<p>There&#8217;s not much to it, but I found this solution to be nice shorthand that cleaned up ugly nested to_xml blocks I was writing over and over.  I call my_record.deep_xml from any layer of the family tree and return a nice drill down of data to the leaf children.  It&#8217;s great if you&#8217;re working with a complicated database and need to be able to present your data in xml.</p>
<h3>If you are so inclined&#8230;</h3>
<p>If you really need to, you can just overwrite the to_xml method in the model.  While fine to do if you know you&#8217;ll always want that one specific template, I avoid it as much as possible and won&#8217;t cover it since examples are all over the blogosphere.  Why not just make a separate function to avoid producing unexpected results for someone else who joins your project later on?</p>
<div id="crp_related"><h3>Related Posts:</h3><ul><li><a href="http://blog.smartlogicsolutions.com/2008/10/10/making-willpaginate-and-rails-to_xml-play-nice-with-activeresource/" rel="bookmark" class="crp_title">Making WillPaginate and Rails to_xml play nice with ActiveResource</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/06/11/multithreading-in-ruby-on-rails/" rel="bookmark" class="crp_title">Multithreading in Ruby on Rails</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/10/28/faking-a-will-paginate-collection-on-an-active-resource-model/" rel="bookmark" class="crp_title">Faking a Will Paginate Collection on an Active Resource model</a></li><li><a href="http://blog.smartlogicsolutions.com/2009/02/24/rails-23-nested-object-forms-im-not-crazy-about-them/" rel="bookmark" class="crp_title">Rails 2.3 Nested Object Forms: I&#8217;m not Crazy about Them</a></li><li><a href="http://blog.smartlogicsolutions.com/2008/07/10/merging-a-has_many-relationship-into-one-instance/" rel="bookmark" class="crp_title">Merging a :has_many relationship into one instance</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://blog.smartlogicsolutions.com/2008/09/10/using-activerecords-to_xml-to-produce-custom-xml-including-deep-level-associations/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>

