<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/atom10full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0" xml:lang="en" xml:base="http://matthewtodd.org/wp-atom.php">
	<title type="text">Matthew Todd</title>
	<subtitle type="text">Software development and life in Moshi, Tanzania</subtitle>

	<updated>2008-09-23T14:36:47Z</updated>
	<generator uri="http://wordpress.org/" version="2.6">WordPress</generator>

	<link rel="alternate" type="text/html" href="http://matthewtodd.org" />
	<id>http://matthewtodd.org/feed/atom/</id>
	

			<logo>http://www.matthewtodd.org/images/matthewtodd_small.jpg</logo><link rel="self" href="http://feeds.feedburner.com/matthewtodd_org" type="application/atom+xml" /><entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Kilimanjaro]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/09/23/kilimanjaro/" />
		<id>http://matthewtodd.org/?p=54</id>
		<updated>2008-09-23T14:36:47Z</updated>
		<published>2008-09-23T14:36:46Z</published>
		<category scheme="http://matthewtodd.org" term="Life" />		<summary type="html"><![CDATA[My trouble with blogging is that when I&#8217;m doing things I&#8217;d write about, I don&#8217;t have any time to write about them. So:
My buddies Michael and Andrew made the trip last month, and we climbed the mountain together!

They&#8217;re both quite good photographers, so I didn&#8217;t even bother carrying a camera. The shot above&#8217;s from Michael&#8217;s [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/09/23/kilimanjaro/"><![CDATA[<p>My trouble with blogging is that when I&#8217;m doing things I&#8217;d write about, I don&#8217;t have any time to write about them. So:</p>
<p>My buddies <a href="http://gotmikhail.com/">Michael</a> and <a href="http://lotzefamily.com/blog/">Andrew</a> made the trip last month, and we climbed the mountain together!</p>
<p><a href="http://flickr.com/photos/gotmikhail/2807861248/"><img src="http://farm4.static.flickr.com/3076/2807861248_bc1f6a2166.jpg" border="0" width="500" height="333" /></a></p>
<p>They&#8217;re both quite good photographers, so I didn&#8217;t even bother carrying a camera. The shot above&#8217;s from <a href="http://www.flickr.com/photos/gotmikhail/sets/72157607002387170/">Michael&#8217;s Tanzania photoset on Flickr</a>, and <a href="http://lotzefamily.com/pictures/2008AUGkili/">Andrew&#8217;s are up (with hilarious comments) on his site</a>.</p>
<p>On the climb, you really come to appreciate the strength and tirelessness of the guides and porters&#8212;and to realize (machismo notwithstanding) that there&#8217;s no way you could make it up the mountain without all these guys carrying your stuff for you.</p>
<p>We climbed with <a href="http://maranguhotel.com/">Marangu Hotel</a>, who take good care of their porters. Many, many companies don&#8217;t, so I&#8217;d encourage you to check out the <a href="http://kiliporters.org/">Kilimanjaro Porters Assistance Project</a> and lend a hand as you&#8217;re able.</p>
<p><a href="http://flickr.com/photos/gotmikhail/2807862012/"><img src="http://farm4.static.flickr.com/3075/2807862012_29d6d1de7f_d.jpg" border="0" width="500" height="333" /></a></p>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/09/23/kilimanjaro/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/09/23/kilimanjaro/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Too much fun]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/29/too-much-fun/" />
		<id>http://www.matthewtodd.org/?p=53</id>
		<updated>2008-04-29T10:31:33Z</updated>
		<published>2008-04-29T10:30:58Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[# ~/.autotest
Autotest.add_hook(:red)      { `say oops` }
Autotest.add_hook(:green)    { `say ok` }
Autotest.add_hook(:all_good) { `say sweet` }

]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/29/too-much-fun/"><![CDATA[<pre class="textmate-source twilight"><code><span class="source source_ruby"><span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span> ~/.autotest
</span><span class="support support_class support_class_ruby">Autotest</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>add_hook<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>red</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>      <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span><span class="string string_interpolated string_interpolated_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">`</span>say oops<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">`</span></span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span>
<span class="support support_class support_class_ruby">Autotest</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>add_hook<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>green</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>    <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span><span class="string string_interpolated string_interpolated_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">`</span>say ok<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">`</span></span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span>
<span class="support support_class support_class_ruby">Autotest</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>add_hook<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>all_good</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span><span class="string string_interpolated string_interpolated_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">`</span>say sweet<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">`</span></span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span>
</span></code></pre>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/29/too-much-fun/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/29/too-much-fun/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Rails tip #5: Atom param parser]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/25/rails-tip-5-atom-param-parser/" />
		<id>http://www.matthewtodd.org/?p=52</id>
		<updated>2008-04-25T11:31:40Z</updated>
		<published>2008-04-25T11:31:24Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[The Atom Publishing Protocol is wonderfully RESTful, so it&#8217;s a natural fit for a Rails application.
One thing you&#8217;ll run into, though, is that AtomPub posts application/atom+xml data rather than the usual application/x-www-form-urlencoded stuff, so you&#8217;ll have to write some extra code to handle it.
The good news is that ActionController::Base helps you out. Instead of having [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/25/rails-tip-5-atom-param-parser/"><![CDATA[<p>The Atom Publishing Protocol is wonderfully RESTful, so it&#8217;s a natural fit for a Rails application.</p>
<p>One thing you&#8217;ll run into, though, is that AtomPub posts <code>application/atom+xml</code> data rather than the usual <code>application/x-www-form-urlencoded</code> stuff, so you&#8217;ll have to write some extra code to handle it.</p>
<p>The good news is that <code>ActionController::Base</code> helps you out. Instead of having to branch on the request type and fatten your controller, you can <a href="http://github.com/rails/rails/tree/c8da518bbfedc2a06b1d96912ddae00e57f21748/actionpack/lib/action_controller/base.rb#L292">register a custom <code>param_parser</code></a>.</p>
<p>So, we wrote <code>Hash.from_atom</code> to transform the incoming xml into the usual <code>{&nbsp;:entry&nbsp;=> {&nbsp;...&nbsp;}&nbsp;}</code> params. Then, we registered it in an initializer:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby source_ruby_rails"><span class="support support_class support_class_ruby">ActionController</span><span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby">::</span><span class="support support_class support_class_ruby">Base</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>param_parsers<span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="support support_class support_class_ruby">Mime</span><span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby">::</span><span class="variable variable_other variable_other_constant variable_other_constant_ruby">ATOM</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> lambda <span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby">do </span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span><span class="variable variable_other variable_other_block variable_other_block_ruby">body</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span>
  <span class="support support_class support_class_ruby">Hash</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>from_atom<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>body<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
<span class="keyword keyword_control keyword_control_ruby">end</span></span></code></pre>
<p>And our controller can now handle either regular form postings or AtomPub entries with the same line of code:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby source_ruby_rails"><span class="meta meta_rails meta_rails_controller"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">EntriesController<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby">&lt;</span> ApplicationController</span></span></span>
  <span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">create</span></span>
    <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>entry</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="variable variable_other variable_other_readwrite variable_other_readwrite_instance variable_other_readwrite_instance_ruby"><span class="punctuation punctuation_definition punctuation_definition_variable punctuation_definition_variable_ruby">@</span>collection</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>entries<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>build<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>params<span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">[</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>entry</span><span class="punctuation punctuation_section punctuation_section_array punctuation_section_array_ruby">]</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
<span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby">    <span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span> ...
</span>  <span class="keyword keyword_control keyword_control_ruby">end</span>
</span><span class="keyword keyword_control keyword_control_ruby">end</span>
</span></code></pre>
<p>Not bad.</p>
<h3>5 Rails tips</h3>
<p>Each day this week, <a href="http://youtube.com/watch?v=J35CuC3ywnc">Joachim</a> and I will post something we&#8217;ve learned in our time programming together. It&#8217;s fun to do, and we might just <a href="http://railscasts.com/contest">win something</a> as well.</p>
<p>So far, we&#8217;ve written:</p>
<ol>
<li><a href="http://www.matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/">Reloadable custom FormBuilder</a></li>
<li><a href="http://www.matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/">Faking DATA in tests</a></li>
<li><a href="http://www.matthewtodd.org/2008/04/23/rails-tip-3-filter-blobs-from-activerecord-logging/">Filter BLOBs from ActiveRecord logging</a></li>
<li><a href="http://www.matthewtodd.org/2008/04/24/rails-tip-4-writing-capistrano-recipes-to-be-loaded-from-gems/">Writing Capistrano recipes to be loaded from gems</a></li>
<li>Atom param parser</li>
</ol>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/25/rails-tip-5-atom-param-parser/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/25/rails-tip-5-atom-param-parser/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Rails tip #4: Writing Capistrano recipes to be loaded from gems]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/24/rails-tip-4-writing-capistrano-recipes-to-be-loaded-from-gems/" />
		<id>http://www.matthewtodd.org/?p=51</id>
		<updated>2008-04-24T15:08:22Z</updated>
		<published>2008-04-24T15:08:12Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[Making a gem of your custom Capistrano recipes is a nice way to remove duplicated knowledge across your Rails projects.
On your first pass, you&#8217;ll probably do what I did: gank and modify capistrano/recipes/deploy.rb.
This works great, but you&#8217;ll find it&#8217;s a little tricky to use your new recipes from a Capfile. It turns out you can&#8217;t [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/24/rails-tip-4-writing-capistrano-recipes-to-be-loaded-from-gems/"><![CDATA[<p>Making a gem of your custom Capistrano recipes is a nice way to remove duplicated knowledge across your Rails projects.</p>
<p>On your first pass, you&#8217;ll probably do what I did: gank and modify <a href="http://github.com/jamis/capistrano/tree/72a254d4221e37dce10e2e7e56b2abe36fc53452/lib/capistrano/recipes/deploy.rb"><code>capistrano/recipes/deploy.rb</code></a>.</p>
<p>This works great, but you&#8217;ll find it&#8217;s a little tricky to use your new recipes from a <code>Capfile</code>. It turns out you can&#8217;t just &#8220;<code>require mygem</code>&#8221; and &#8220;<code>load 'mygem/recipes/deploy'</code>&#8221; because Capistrano doesn&#8217;t <code>load</code> from ruby&#8217;s <code>$LOAD_PATH</code>&#8212;it keeps its own <a href="http://github.com/jamis/capistrano/tree/72a254d4221e37dce10e2e7e56b2abe36fc53452/lib/capistrano/configuration/loading.rb#L57">minimally-initialized</a> <code>load_paths</code> setting instead.</p>
<p>So, you have to either modify the <code>load_paths</code> or use an absolute path, like this:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby"><span class="string string_quoted string_quoted_other string_quoted_other_literal string_quoted_other_literal_lower string_quoted_other_literal_lower_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">%w(</span> rubygems wordpress <span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">)</span></span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>each <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span><span class="variable variable_other variable_other_block variable_other_block_ruby">lib</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span> <span class="meta meta_require meta_require_ruby"><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">require</span> lib <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span></span>
load <span class="support support_class support_class_ruby">Gem</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>required_location<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>wordpress<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>wordpress/recipes/deploy.rb<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
load <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>config/deploy<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span>
</span></code></pre>
<p>This is what I did for a while, but something didn&#8217;t seem right. My <code>Capfile</code> didn&#8217;t look as nice as I expected, and I wasn&#8217;t using <a href="http://github.com/jamis/capistrano/tree/72a254d4221e37dce10e2e7e56b2abe36fc53452/lib/capistrano/configuration/loading.rb#L104"><code>require</code></a>, whose comments clearly mention third-party recipes.</p>
<h3>Take two</h3>
<p>Staring at <code>capistrano/configuration/loading.rb</code> until it made sense, I saw <a href="http://github.com/jamis/capistrano/tree/72a254d4221e37dce10e2e7e56b2abe36fc53452/lib/capistrano/configuration/loading.rb#L11"><code>instance</code></a>, which triggered some vague distant memory that somehow turned into a productive thought:</p>
<p>If you wrap your <code>deploy.rb</code> recipes in a load block, like this:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby source_ruby_rails"><span class="support support_class support_class_ruby">Capistrano</span><span class="punctuation punctuation_separator punctuation_separator_other punctuation_separator_other_ruby">::</span><span class="support support_class support_class_ruby">Configuration</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>instance<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>must_exist</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>load <span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby">do
</span><span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby">  <span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span> previous file contents here
</span><span class="keyword keyword_control keyword_control_ruby">end</span></span></code></pre>
<p>You can simplify your <code>Capfile</code> with a shorter <code>require</code> statement:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby"><span class="meta meta_require meta_require_ruby"><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">require</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>rubygems<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span></span>
<span class="meta meta_require meta_require_ruby"><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">require</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>wordpress/recipes/deploy<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span></span>
load    <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>config/deploy<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span>
</span></code></pre>
<p>Nice. I&#8217;m still a little bummed by the <code>require</code> / <code>load</code> imbalance, but on the whole this feels more like things were supposed to be.</p>
<h3>5 Rails tips</h3>
<p>Each day this week, <a href="http://youtube.com/watch?v=J35CuC3ywnc">Joachim</a> and I will post something we&#8217;ve learned in our time programming together. It&#8217;s fun to do, and we might just <a href="http://railscasts.com/contest">win something</a> as well.</p>
<p>So far, we&#8217;ve written:</p>
<ol>
<li><a href="http://www.matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/">Reloadable custom FormBuilder</a></li>
<li><a href="http://www.matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/">Faking DATA in tests</a></li>
<li><a href="http://www.matthewtodd.org/2008/04/23/rails-tip-3-filter-blobs-from-activerecord-logging/">Filter BLOBs from ActiveRecord logging</a></li>
<li>Writing Capistrano recipes to be loaded from gems</li>
</ol>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/24/rails-tip-4-writing-capistrano-recipes-to-be-loaded-from-gems/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/24/rails-tip-4-writing-capistrano-recipes-to-be-loaded-from-gems/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Rails tip #3: Filter BLOBs from ActiveRecord logging]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/23/rails-tip-3-filter-blobs-from-activerecord-logging/" />
		<id>http://www.matthewtodd.org/?p=50</id>
		<updated>2008-04-23T07:35:40Z</updated>
		<published>2008-04-23T07:35:17Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[We threw attachment_fu into our app the other day, starting off with the default :db_file setting to store images in the database. (I&#8217;ve been bitten by this approach before, but this time around I&#8217;m intrigued by page caching. We&#8217;ll see.)
In the meantime, we&#8217;ve got blob after blob flying by in the script/server output, and it&#8217;s [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/23/rails-tip-3-filter-blobs-from-activerecord-logging/"><![CDATA[<p>We threw <a href="http://github.com/technoweenie/attachment_fu"><code>attachment_fu</code></a> into our app the other day, starting off with the default <code>:db_file</code> setting to store images in the database. (I&#8217;ve been bitten by this approach before, but this time around I&#8217;m intrigued by page caching. We&#8217;ll see.)</p>
<p>In the meantime, we&#8217;ve got blob after blob flying by in the <code>script/server</code> output, and it&#8217;s messing up our <code>Terminal</code> fonts. No good.</p>
<p>Here&#8217;s a quick fix, <code>config/initializers/filter_db_files_logging.rb</code>:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby source_ruby_rails"><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">ActiveRecord::ConnectionAdapters::AbstractAdapter</span></span>
  <span class="meta meta_function meta_function_method meta_function_method_with-arguments meta_function_method_with-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">format_log_entry_with_db_files_filtering</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_ruby">message<span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> dump <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="constant constant_language constant_language_ruby">nil</span></span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_ruby">)</span></span>
    dump <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>INSERT INTO db_files<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span> <span class="keyword keyword_control keyword_control_ruby">if</span> dump<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>to_s <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">=~</span> <span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span>^INSERT INTO db_files<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span></span>
    dump <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>UPDATE db_files<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span>      <span class="keyword keyword_control keyword_control_ruby">if</span> dump<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>to_s <span class="keyword keyword_operator keyword_operator_comparison keyword_operator_comparison_ruby">=~</span> <span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span>^UPDATE db_files<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span></span>
    format_log_entry_without_db_files_filtering<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>message<span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> dump<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>

  alias_method_chain <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>format_log_entry</span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="constant constant_other constant_other_symbol constant_other_symbol_ruby"><span class="punctuation punctuation_definition punctuation_definition_constant punctuation_definition_constant_ruby">:</span>db_files_filtering</span>
<span class="keyword keyword_control keyword_control_ruby">end</span></span></code></pre>
<p>Note that this isn&#8217;t yet a general solution (other tables&#8217; blobs will still be logged), but it&#8217;s good enough for our needs, and we&#8217;ve got a known place we can come back to should we need to filter more blobs in the future.</p>
<p>Also, looking at <a href="http://github.com/rails/rails/tree/c8da518bbfedc2a06b1d96912ddae00e57f21748/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb#L120"><code>AbstractAdapter#log_info</code></a> just now, we notice that could have written our own <code>Logger</code> and saved the monkeypatch. Maybe we&#8217;ll look into doing that some day.</p>
<h3>5 Rails tips</h3>
<p>Each day this week, <a href="http://youtube.com/watch?v=J35CuC3ywnc">Joachim</a> and I will post something we&#8217;ve learned in our time programming together. It&#8217;s fun to do, and we might just <a href="http://railscasts.com/contest">win something</a> as well.</p>
<p>So far, we&#8217;ve written:</p>
<ol>
<li><a href="http://www.matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/">Reloadable custom FormBuilder</a></li>
<li><a href="http://www.matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/">Faking DATA in tests</a></li>
<li>Filter BLOBs from ActiveRecord logging</li>
</ol>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/23/rails-tip-3-filter-blobs-from-activerecord-logging/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/23/rails-tip-3-filter-blobs-from-activerecord-logging/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Rails tip #2: Faking DATA in tests]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/" />
		<id>http://www.matthewtodd.org/?p=49</id>
		<updated>2008-04-22T09:00:34Z</updated>
		<published>2008-04-22T08:58:31Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[Ruby gives you access to the raw text after an __END__ statement in the currently running file through the DATA IO object.
Sometimes you&#8217;d like to use DATA in a test. You&#8217;ll find it works when you run the test individually but then fails when you run the whole suite. (Remember DATA comes from $0, the [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/"><![CDATA[<p>Ruby gives you access to the raw text after an <code>__END__</code> statement in the currently running file through the <code>DATA</code> <code>IO</code> object.</p>
<p>Sometimes you&#8217;d like to use <code>DATA</code> in a test. You&#8217;ll find it works when you run the test individually but then fails when you run the whole suite. (Remember <code>DATA</code> comes from <code>$0</code>, the currently running file, only.)</p>
<p>We&#8217;ve found <a href="http://codeforpeople.rubyforge.org/svn/rubyforge/tags/0.4.5/lib/rubyforge.rb">a nice way to fake it</a> in the rubyforge gem: <code>read</code> <code>__FILE__</code> instead, then <code>split</code> the results.</p>
<p>Here&#8217;s an example of the technique in use, functionally testing a wiki parser we&#8217;ve been tinkering with. It can often be <a href="http://blog.jayfields.com/2008/03/testing-anti-pattern-metaprogrammed.html">painful to work with metaprogrammed tests</a> like this, but on balance, we like the results here:</p>
<pre class="textmate-source twilight"><code><span class="source source_ruby source_ruby_rails"><span class="meta meta_require meta_require_ruby"><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">require</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>test_helper<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span></span>

<span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">TestParser<span class="entity entity_other entity_other_inherited-class entity_other_inherited-class_ruby"> <span class="punctuation punctuation_separator punctuation_separator_inheritance punctuation_separator_inheritance_ruby">&lt;</span> Test::Unit::TestCase</span></span></span>
  <span class="variable variable_other variable_other_constant variable_other_constant_ruby">EXAMPLES</span> <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span>=<span class="string string_regexp string_regexp_arbitrary-repitition string_regexp_arbitrary-repitition_ruby"><span class="punctuation punctuation_definition punctuation_definition_arbitrary-repitition punctuation_definition_arbitrary-repitition_ruby">{</span>80<span class="punctuation punctuation_definition punctuation_definition_arbitrary-repitition punctuation_definition_arbitrary-repitition_ruby">}</span></span><span class="constant constant_character constant_character_escape constant_character_escape_ruby">\n</span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/m</span></span>
  <span class="variable variable_other variable_other_constant variable_other_constant_ruby">PARTS</span>    <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span>-<span class="string string_regexp string_regexp_arbitrary-repitition string_regexp_arbitrary-repitition_ruby"><span class="punctuation punctuation_definition punctuation_definition_arbitrary-repitition punctuation_definition_arbitrary-repitition_ruby">{</span>80<span class="punctuation punctuation_definition punctuation_definition_arbitrary-repitition punctuation_definition_arbitrary-repitition_ruby">}</span></span><span class="constant constant_character constant_character_escape constant_character_escape_ruby">\n</span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/m</span></span>

<span class="comment comment_line comment_line_number-sign comment_line_number-sign_ruby">  <span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_ruby">#</span> Faking data = DATA.read
</span>  data <span class="keyword keyword_operator keyword_operator_assignment keyword_operator_assignment_ruby">=</span> <span class="support support_class support_class_ruby">File</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>read<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="variable variable_language variable_language_ruby">__FILE__</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>split<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>__END__<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>last

  data<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>split<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="variable variable_other variable_other_constant variable_other_constant_ruby">EXAMPLES</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>map <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">{</span><span class="meta meta_syntax meta_syntax_ruby meta_syntax_ruby_start-block"> </span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span><span class="variable variable_other variable_other_block variable_other_block_ruby">example</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span> example<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>split<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="variable variable_other variable_other_constant variable_other_constant_ruby">PARTS</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span> <span class="punctuation punctuation_section punctuation_section_scope punctuation_section_scope_ruby">}</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>each <span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby">do </span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span><span class="variable variable_other variable_other_block variable_other_block_ruby">comment</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">,</span> <span class="variable variable_other variable_other_block variable_other_block_ruby">markup</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">,</span> <span class="variable variable_other variable_other_block variable_other_block_ruby">html</span><span class="punctuation punctuation_separator punctuation_separator_variable punctuation_separator_variable_ruby">|</span>
    define_method <span class="string string_quoted string_quoted_double string_quoted_double_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">"</span>test_<span class="source source_ruby source_ruby_embedded source_ruby_embedded_source"><span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby">#{</span>comment<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>strip<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>downcase<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>gsub<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span><span class="string string_regexp string_regexp_classic string_regexp_classic_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span><span class="constant constant_character constant_character_escape constant_character_escape_ruby">\W</span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_ruby">/</span></span><span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="string string_quoted string_quoted_single string_quoted_single_ruby"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_ruby">'</span>_<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">'</span></span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_section punctuation_section_embedded punctuation_section_embedded_ruby">}</span></span><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_ruby">"</span></span> <span class="keyword keyword_control keyword_control_start-block keyword_control_start-block_ruby">do
</span>      assert_equal html<span class="punctuation punctuation_separator punctuation_separator_object punctuation_separator_object_ruby">,</span> <span class="support support_class support_class_ruby">Parser</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span><span class="keyword keyword_other keyword_other_special-method keyword_other_special-method_ruby">new</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>parse<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">(</span>markup<span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_ruby">)</span><span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>result<span class="punctuation punctuation_separator punctuation_separator_method punctuation_separator_method_ruby">.</span>to_html
    <span class="keyword keyword_control keyword_control_ruby">end</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>
<span class="keyword keyword_control keyword_control_ruby">end</span>

<span class="string string_unquoted string_unquoted_program-block string_unquoted_program-block_ruby">__END__
</span><span class="text text_plain">A single wiki word should be linked and wrapped in a paragraph.
--------------------------------------------------------------------------------
WikiWord
--------------------------------------------------------------------------------
&lt;p&gt;&lt;a href="WikiWord"&gt;WikiWord&lt;/a&gt;&lt;/p&gt;
================================================================================
Two wiki words on separate lines should become two paragraphs
--------------------------------------------------------------------------------
WikiWord
WikiWord
--------------------------------------------------------------------------------
&lt;p&gt;&lt;a href="WikiWord"&gt;WikiWord&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="WikiWord"&gt;WikiWord&lt;/a&gt;&lt;/p&gt;
</span></span></code></pre>
<h3>5 Rails tips</h3>
<p>Each day this week, <a href="http://youtube.com/watch?v=J35CuC3ywnc">Joachim</a> and I will post something we&#8217;ve learned in our time programming together. It&#8217;s fun to do, and we might just <a href="http://railscasts.com/contest">win something</a> as well.</p>
<p>So far, we&#8217;ve written:</p>
<ol>
<li><a href="http://www.matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/">Reloadable custom FormBuilder</a></li>
<li>Faking DATA in tests</li>
</ol>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/22/rails-tip-2-faking-data-in-tests/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Rails tip #1: Reloadable custom FormBuilder]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/" />
		<id>http://www.matthewtodd.org/?p=48</id>
		<updated>2008-04-21T08:28:21Z</updated>
		<published>2008-04-21T08:25:58Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[August Lilleaas has a nice writeup on making your own FormBuilder. Towards the end, he describes wiring it up as the default:

Create a new file called config/initializers/setup.rb. Or, if you’re on pre-2.0, add it to the bottom of config/environment.rb:
ActionView::Base.default_form_builder = LabellingFormBuilder

Though &#8220;proper,&#8221; this approach requires restarting the server to see changes in LabellingFormBuilder.
You can avoid [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/"><![CDATA[<p>August Lilleaas has <a href="http://august.lilleaas.net/posts/form-builders-are-easy">a nice writeup</a> on making your own <code>FormBuilder</code>. Towards the end, he describes wiring it up as the default:</p>
<blockquote>
<p>Create a new file called <code>config/initializers/setup.rb</code>. Or, if you’re on pre-2.0, add it to the bottom of <code>config/environment.rb</code>:</p>
<p><code>ActionView::Base.default_form_builder = LabellingFormBuilder</code></p>
</blockquote>
<p>Though &#8220;proper,&#8221; this approach requires restarting the server to see changes in <code>LabellingFormBuilder</code>.</p>
<p>You can avoid restarting the server by doing this instead:</p>
<pre class="textmate-source twilight"><code><span class="meta meta_class meta_class_ruby"><span class="keyword keyword_control keyword_control_class keyword_control_class_ruby">class</span> <span class="entity entity_name entity_name_type entity_name_type_class entity_name_type_class_ruby">ActionView::Base</span></span>
  <span class="meta meta_function meta_function_method meta_function_method_without-arguments meta_function_method_without-arguments_ruby"><span class="keyword keyword_control keyword_control_def keyword_control_def_ruby">def</span> <span class="entity entity_name entity_name_function entity_name_function_ruby">self.default_form_builder</span></span>
    <span class="variable variable_other variable_other_constant variable_other_constant_ruby">LabellingFormBuilder</span>
  <span class="keyword keyword_control keyword_control_ruby">end</span>
<span class="keyword keyword_control keyword_control_ruby">end</span></span></code></pre>
<p>It&#8217;s a subtle difference, but it provides a nice window into understanding the <code>Dependencies</code> mechanism:</p>
<p>In August&#8217;s version, <a href="http://github.com/rails/rails/tree/f757f5838818ce35f7927a10a8cda6f9583869c5/activesupport/lib/active_support/dependencies.rb#L446"><code>const_missing</code></a> loads the <code>LabellingFormBuilder</code> class only once, when the initializer is run.</p>
<p>In our version, we&#8217;ve tricked <code>const_missing</code> into running on each request by <em>not holding onto the class it loads</em>. That is, instead of caching the class lookup in <code>@@default_form_builder</code>, we&#8217;re allowing the lookup to be performed on demand.</p>
<p>Sweet.</p>
<h3>5 Rails tips</h3>
<p>Each day this week, <a href="http://youtube.com/watch?v=J35CuC3ywnc">Joachim</a> and I will post something we&#8217;ve learned in our time programming together. It&#8217;s fun to do, and we might just <a href="http://railscasts.com/contest">win something</a> as well.</p>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/21/rails-tip-1-reloadable-custom-formbuilder/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[doh 0.2.1]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/09/doh-021/" />
		<id>http://www.matthewtodd.org/?p=47</id>
		<updated>2008-04-09T10:54:43Z</updated>
		<published>2008-04-09T10:37:45Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[Doh stops your version control commit if you&#8217;ve forgotten to add some files.
I last wrote about Doh in August. You may remember this part:

DDDDDDDDDDDDD                         hhhhhhh
 D::::::::::::DDD      [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/09/doh-021/"><![CDATA[<p>Doh stops your version control commit if you&#8217;ve forgotten to add some files.</p>
<p>I last <a href="http://www.matthewtodd.org/2007/08/17/preventing-commits-with-unadded-files/">wrote about Doh</a> in August. You may remember this part:</p>
<pre><code>
DDDDDDDDDDDDD                         hhhhhhh
 D::::::::::::DDD                      h:::::h
 D:::::::::::::::DD                    h:::::h
 DDD:::::DDDDD:::::D                   h:::::h
   D:::::D    D:::::D    ooooooooooo    h::::h hhhhh
   D:::::D     D:::::D oo:::::::::::oo  h::::hh:::::hhh
   D:::::D     D:::::Do:::::::::::::::o h::::::::::::::hh
   D:::::D     D:::::Do:::::ooooo:::::o h:::::::hhh::::::h
   D:::::D     D:::::Do::::o     o::::o h::::::h   h::::::h
   D:::::D     D:::::Do::::o     o::::o h:::::h     h:::::h
   D:::::D     D:::::Do::::o     o::::o h:::::h     h:::::h
   D:::::D    D:::::D o::::o     o::::o h:::::h     h:::::h
 DDD:::::DDDDD:::::D  o:::::ooooo:::::o h:::::h     h:::::h
 D:::::::::::::::DD   o:::::::::::::::o h:::::h     h:::::h ......
 D::::::::::::DDD      oo:::::::::::oo  h:::::h     h:::::h .::::.
 DDDDDDDDDDDDD           ooooooooooo    hhhhhhh     hhhhhhh ......
</code></pre>
<p>Since then, some nice things have happened:</p>
<ul>
<li>
<p>It&#8217;s a (<a href="http://docs.matthewtodd.org/doh">somewhat documented</a>) gem:</p>
<pre><code>$ gem install doh --source http://gems.matthewtodd.org</code></pre>
</li>
<li>
<p>It has <code>git</code> support!</p>
<p>Doh tries to be smart about <code>git commit -a</code>, staying out of your way if you&#8217;ve only modified or deleted tracked files (exactly the things <code>-a</code> notices). See also the <a href="http://git.matthewtodd.org/?p=doh.git;a=blob;f=test/test_git.rb;h=6d15608043bbfa563937ce1bb300e120eca23edc;hb=922f7e84202b7ace05bd2e6d613c1b7a9f1fddae">test case</a>.</p>
</li>
</ul>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/09/doh-021/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/09/doh-021/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[git st]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/04/09/git-st/" />
		<id>http://www.matthewtodd.org/?p=46</id>
		<updated>2008-04-09T10:53:09Z</updated>
		<published>2008-04-09T06:46:09Z</published>
		<category scheme="http://matthewtodd.org" term="Technical" />		<summary type="html"><![CDATA[
[shoes:~/Code/wordpress] mtodd$ git st
git: &#39;st&#39; is not a git-command. See &#39;git &#45;&#45;help&#39;.
[shoes:~/Code/wordpress] mtodd$ git config &#45;&#45;global alias.st status
[shoes:~/Code/wordpress] mtodd$ git st
# On branch master
nothing to commit (working directory clean)
[shoes:~/Code/wordpress] mtodd$

]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/04/09/git-st/"><![CDATA[<pre><code>
[shoes:~/Code/wordpress] <span style="font-weight:normal; color:blue">mtodd</span>$ git st
git: &#39;st&#39; is not a git-command. See &#39;git &#45;&#45;help&#39;.
[shoes:~/Code/wordpress] <span style="font-weight:normal; color:blue">mtodd</span>$ git config &#45;&#45;global alias.st status
[shoes:~/Code/wordpress] <span style="font-weight:normal; color:blue">mtodd</span>$ git st
# On branch master
nothing to commit (working directory clean)
[shoes:~/Code/wordpress] <span style="font-weight:normal; color:blue">mtodd</span>$
</code></pre>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/04/09/git-st/#comments" thr:count="0" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/04/09/git-st/feed/atom/" thr:count="0" />
		<thr:total>0</thr:total>
	</entry>
		<entry>
		<author>
			<name>Matthew Todd</name>
						<uri>http://www.matthewtodd.org/</uri>
					</author>
		<title type="html"><![CDATA[Marathon]]></title>
		<link rel="alternate" type="text/html" href="http://matthewtodd.org/2008/03/20/marathon/" />
		<id>http://www.matthewtodd.org/2008/03/20/marathon/</id>
		<updated>2008-03-20T10:58:27Z</updated>
		<published>2008-03-20T10:57:54Z</published>
		<category scheme="http://matthewtodd.org" term="Life" />		<summary type="html"><![CDATA[Looking back at the marathon, I feel really good about it. I had tried to stick well to this novice training schedule I&#8217;d found online, and by the morning of the race, even though the bottom was dropping out of my chest, I knew I&#8217;d be able to finish alright.
I cued up &#8220;Where the Streets [...]]]></summary>
		<content type="html" xml:base="http://matthewtodd.org/2008/03/20/marathon/"><![CDATA[<p>Looking back at the marathon, I feel really good about it. I had tried to stick well to this <a href="http://www.halhigdon.com/marathon/novices.html">novice training schedule</a> I&#8217;d found online, and by the morning of the race, even though the bottom was dropping out of my chest, I knew I&#8217;d be able to finish alright.</p>
<p>I cued up &#8220;<a href="http://en.wikipedia.org/wiki/Where_the_Streets_Have_No_Name">Where the Streets Have No Name</a>&#8221; on Karen&#8217;s iPod at the starting line, waiting to push play until they said go. I hadn&#8217;t remembered the first line, but as I was turning left out the cooperative college gate onto the main road, Bono came in with &#8220;I want to run,&#8221; and holy cow, I almost lost it.</p>
<p>Running itself was pretty much normal. I was worried about starting off too fast, so I found a few people who looked like they were going at a good pace, and we stuck together through the first half of the race.</p>
<p>After that, Karen&#8217;s marathon support plan kicked into full gear&#8212;she&#8217;d stationed people <em>every mile</em> with all sorts of gummy bears, jelly beans, water bottles, potato chips, and sponge buckets. It was fun!</p>
<p>Some of them even ran along with me for a while, which was <em>super</em> encouraging. Jen pushed Benjamin in the stroller, Joe told me corny programmer jokes, and Aaron just kept running&#8212;for 11 miles! Here we are coming down the hill with 2&frac12; left. </p>
<p><a href="http://www.flickr.com/photos/mtodd/2342782068" title="View 'Not Dead Yet' on Flickr.com"><img src="http://farm3.static.flickr.com/2357/2342782068_d65438417c.jpg" alt="Not Dead Yet" border="0" width="500" height="375" /></a></p>
<p>During those last couple of miles, my quads started cramping and a blister popped on my little toe, but by then it was hard to care about much of anything.</p>
<p>By the time I got to the finish line, I could keep running, but I think that was only because of developed habit, not because I actually had anything left. I don&#8217;t think I&#8217;ve ever felt so right cursing in desperation before.</p>
<p><a href="http://www.flickr.com/photos/mtodd/2341951445" title="View 'Finish' on Flickr.com"><img src="http://farm3.static.flickr.com/2409/2341951445_0f2baa7f05.jpg" alt="Finish" border="0" width="500" height="375" /></a></p>
<p>Two and a half weeks later, I&#8217;m feeling great, and totally eager to keep running. There&#8217;s supposed to be a <a href="http://www.serengetimarathon.com/run/index.php/serengeti-half-marathon/">half-marathon in the Serengeti</a> in June, and it looks like there are some other folks here who&#8217;d also be interested&#8212;though it&#8217;ll be one heckuva road trip to get all the way out there!</p>
<p>Also, thanks so much to all of you who helped <a href="http://www.matthewtodd.org/2008/02/08/running-for-the-kilimanjaro-porters-assistance-project/">support</a> the Porters Assistance Project. We came in over our goal, and Karen&#8217;s thrilled!</p>
]]></content>
		<link rel="replies" type="text/html" href="http://matthewtodd.org/2008/03/20/marathon/#comments" thr:count="3" />
		<link rel="replies" type="application/atom+xml" href="http://matthewtodd.org/2008/03/20/marathon/feed/atom/" thr:count="3" />
		<thr:total>3</thr:total>
	</entry>
	</feed>
