<?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>Cretaceous Labs &#187; Ruby</title>
	<atom:link href="http://cretaceouslabs.com/blog/category/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://cretaceouslabs.com/blog</link>
	<description></description>
	<lastBuildDate>Sun, 10 Oct 2010 20:02:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.5</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Default stegosaurses</title>
		<link>http://cretaceouslabs.com/blog/2009/01/default-stegosaurses/</link>
		<comments>http://cretaceouslabs.com/blog/2009/01/default-stegosaurses/#comments</comments>
		<pubDate>Thu, 29 Jan 2009 00:10:00 +0000</pubDate>
		<dc:creator>nick</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[ActiveRecord]]></category>
		<category><![CDATA[Testing]]></category>

		<guid isPermaLink="false">http://cretaceouslabs.com/blog/2009/01/default-stegosaurses/</guid>
		<description><![CDATA[Ever heard of Jonathan Viney&#8217;s active_record_defaults plugin? It&#8217;s fantastic. In a nutshell, it enables you to specify default values for model attributes. If an attribute isn&#8217;t set when initialising a new instance, the attribute&#8217;s set to whatever the default value is.
For example, let&#8217;s rebuild that Stegosaurus class from a previous post:
class Stegosaurus &#60; ActiveRecord::Base  [...]]]></description>
			<content:encoded><![CDATA[<p>Ever heard of Jonathan Viney&#8217;s <a href="http://svn.viney.net.nz/things/rails/plugins/active_record_defaults/">active_record_defaults</a> plugin? It&#8217;s fantastic. In a nutshell, it enables you to specify default values for model attributes. If an attribute isn&#8217;t set when initialising a new instance, the attribute&#8217;s set to whatever the default value is.</p>
<p>For example, let&#8217;s rebuild that Stegosaurus class from a <a href="http://nick-hoffman.blogspot.com/2009/01/friends-dont-let-friends-code-without.html">previous post</a>:
<pre><span class="keyword">class </span><span class="class">Stegosaurus</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>  <span class="ident">attr_accessible</span> <span class="symbol">:tail_spikes</span><span class="punct">,</span> <span class="symbol">:back_plates</span>

  <span class="ident">validates_numericality_of</span> <span class="symbol">:tail_spikes</span><span class="punct">,</span>    <span class="symbol"> <img src='http://cretaceouslabs.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly_integer</span>             <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>    <span class="symbol">:greater_than_or_equal_to</span> <span class="punct">=&gt;</span> <span class="number">0</span>

  <span class="ident">validates_numericality_of</span> <span class="symbol">:back_plates</span><span class="punct">,</span>    <span class="symbol"> <img src='http://cretaceouslabs.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly_integer</span>             <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>    <span class="symbol">:greater_than_or_equal_to</span> <span class="punct">=&gt;</span> <span class="number">0</span><span class="keyword">end</span></pre>
<p>With that, if we created a new Stegosaurus and didn&#8217;t specify any attributes, not only would it have no tail spikes or back plates, but the model instance wouldn&#8217;t be valid.</p>
<p>To fix that, all we need to do is add two lines:
<pre><span class="keyword">class </span><span class="class">Stegosaurus</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>  <span class="ident">attr_accessible</span> <span class="symbol">:tail_spikes</span><span class="punct">,</span> <span class="symbol">:back_plates</span>

  <span class="ident">default</span> <span class="symbol">:tail_spikes</span> <span class="punct">=&gt;</span> <span class="number">4</span>  <span class="ident">default</span> <span class="symbol">:back_plates</span> <span class="punct">=&gt;</span> <span class="number">6</span>

  <span class="ident">validates_numericality_of</span> <span class="symbol">:tail_spikes</span><span class="punct">,</span>    <span class="symbol"> <img src='http://cretaceouslabs.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly_integer</span>             <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>    <span class="symbol">:greater_than_or_equal_to</span> <span class="punct">=&gt;</span> <span class="number">0</span>

  <span class="ident">validates_numericality_of</span> <span class="symbol">:back_plates</span><span class="punct">,</span>    <span class="symbol"> <img src='http://cretaceouslabs.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly_integer</span>             <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>    <span class="symbol">:greater_than_or_equal_to</span> <span class="punct">=&gt;</span> <span class="number">0</span><span class="keyword">end</span></pre>
<p>And voila, new Stegosaurus objects will automatically have 4 tail spikes and 6 back plates:
<pre>&gt;&gt; s = Stegosaurus.new=&gt; #&lt;Stegosaurus tail_spikes: 4, back_plates: 6&gt;&gt;&gt; ?&gt; s.tail_spikes=&gt; 4&gt;&gt; s.back_plates=&gt; 6</pre>
<p>However, if used improperly, this can lead to several hours of pounding your head on your desk. Note that that the default values we used above, 4 and 6, are immutable objects. You can&#8217;t change them. You can perform operations on them, such as addition (4 + 1), but that never <b>changes</b> the object.</p>
<p>Say we want our Stegosaurus class to have an array specifying its diet that defaults to &#8220;fern&#8221; and &#8220;cycad&#8221;:
<pre><span class="keyword">class </span><span class="class">Stegosaurus</span> <span class="punct">&lt;</span> <span class="constant">ActiveRecord</span><span class="punct">::</span><span class="constant">Base</span>  <span class="ident">attr_accessible</span> <span class="symbol">:tail_spikes</span><span class="punct">,</span> <span class="symbol">:back_plates</span><span class="punct">,</span> <span class="symbol">:diet</span>

  <span class="ident">default</span> <span class="symbol">:tail_spikes</span> <span class="punct">=&gt;</span> <span class="number">4</span>  <span class="ident">default</span> <span class="symbol">:back_plates</span> <span class="punct">=&gt;</span> <span class="number">6</span>  <span class="ident">default</span> <span class="symbol">:diet</span> <span class="punct">=&gt;</span> <span class="punct">%w(</span><span class="string">fern cycad</span><span class="punct">)</span>

  <span class="ident">validates_numericality_of</span> <span class="symbol">:tail_spikes</span><span class="punct">,</span>    <span class="symbol"> <img src='http://cretaceouslabs.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly_integer</span>             <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>    <span class="symbol">:greater_than_or_equal_to</span> <span class="punct">=&gt;</span> <span class="number">0</span>

  <span class="ident">validates_numericality_of</span> <span class="symbol">:back_plates</span><span class="punct">,</span>    <span class="symbol"> <img src='http://cretaceouslabs.com/blog/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly_integer</span>             <span class="punct">=&gt;</span> <span class="constant">true</span><span class="punct">,</span>    <span class="symbol">:greater_than_or_equal_to</span> <span class="punct">=&gt;</span> <span class="number">0</span><span class="keyword">end</span></pre>
<p>That looks right. But watch this:
<pre>=&gt; charles = Stegosaurus.new=&gt; #&lt;Stegosaurus tail_spikes: 4, back_plates: 6, diet: ["fern", "cycad"]&gt;&gt;&gt; ?&gt; arnold = Stegosaurus.new=&gt; #&lt;Stegosaurus tail_spikes: 4, back_plates: 6, diet: ["fern", "cycad"]&gt;&gt;&gt; ?&gt; charles.diet < < 'moss'=&gt; ["fern", "cycad", "moss"]&gt;&gt; ?&gt; arnold.diet=&gt; ["fern", "cycad", "moss"]</pre>
<p>We didn&#8217;t mean to do that&#8230;Arnold doesn&#8217;t want to eat moss!</p>
<p>At the moment, when the Stegosaurus class is initialised, it creates one Array for the default &#8220;diet&#8221; attribute of all future Stegosaurus objects. In other words, Charles&#8217; and Arnolds&#8217; &#8220;diet&#8221; attributes were references to the same object:
<pre>&gt;&gt; charles.diet.object_id=&gt; 19103090&gt;&gt; ?&gt; arnold.diet.object_id=&gt; 19103090</pre>
<p>How do we fix that? We tell the Stegosaurus class to create a new Array for each model instance. Simply change this:
<pre><span class="ident">default</span> <span class="symbol">:diet</span> <span class="punct">=&gt;</span> <span class="punct">%w(</span><span class="string">fern cycad</span><span class="punct">)</span></pre>
<p>to this:
<pre><span class="ident">default</span> <span class="symbol">:diet</span> <span class="punct">=&gt;</span> <span class="constant">Proc</span><span class="punct">.</span><span class="ident">new</span> <span class="punct">{</span> <span class="punct">%w(</span><span class="string">fern cycad</span><span class="punct">)</span> <span class="punct">}</span></pre>
<p>Now each time we create a new Stegosaurus, that Proc will fire, and create a new &#8220;diet&#8221; Array:
<pre>=&gt; charles = Stegosaurus.new=&gt; #&lt;Stegosaurus tail_spikes: 4, back_plates: 6, diet: ["fern", "cycad"]&gt;&gt;&gt; ?&gt; arnold = Stegosaurus.new=&gt; #&lt;Stegosaurus tail_spikes: 4, back_plates: 6, diet: ["fern", "cycad"]&gt;&gt;&gt; ?&gt; charles.diet < < 'moss'=&gt; ["fern", "cycad", "moss"]&gt;&gt; ?&gt; arnold.diet=&gt; ["fern", "cycad"]</pre>
<p>I highly recommend giving <a href="http://svn.viney.net.nz/things/rails/plugins/active_record_defaults/">active_record_defaults</a> a try. It&#8217;s very handy, and very easy to use.</p>
<p>And by the way, yes, I was bitten by this problem. Why else would I be writing about it! Can you guess how I discovered it, though? &#8230; My <a href="http://nick-hoffman.blogspot.com/2009/01/testingits-what-lifes-all-about.html">tests</a> picked it up!</p>
]]></content:encoded>
			<wfw:commentRss>http://cretaceouslabs.com/blog/2009/01/default-stegosaurses/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

