<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Mark Daggett's Blog]]></title>
  <link href="http://heavysixer.github.com/atom.xml" rel="self"/>
  <link href="http://heavysixer.github.com/"/>
  <updated>2012-04-29T13:23:53-05:00</updated>
  <id>http://heavysixer.github.com/</id>
  <author>
    <name><![CDATA[Mark Daggett]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Reading RFID Cards With Ruby and the Mac]]></title>
    <link href="http://heavysixer.github.com/blog/2012/04/23/reading-rfid-cards-with-ruby/"/>
    <updated>2012-04-23T09:18:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/04/23/reading-rfid-cards-with-ruby</id>
    <content type="html"><![CDATA[<p>This weekend I fooled around with the Sparkfun &#8220;RFID Starter Kit&#8221;. I purchased it from my local technology barn for around $50.00. I am teaching myself physical computing, and projects like that can be completed in an afternoon, are a great way to learn &#8220;just enough&#8221; to keep a junior hardware hacker like myself from getting frustrated.</p>

<p>I was thrilled to find out that getting this board to talk to Ruby took virtually no effort. In fact, it was so simple it almost felt like I was cheating some how. Here are the steps that I followed to get the ID-12 RFID Scanner and Reader talking to Ruby.</p>

<ol>
<li><p>Download the most recent drivers from Future Technology Devices International:
 <a href="http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_14.dmg">http://www.ftdichip.com/Drivers/VCP/MacOSX/FTDIUSBSerialDriver_v2_2_14.dmg</a>
 The package contains two sets of drivers. Make sure that you install the version that is right for your operating system.</p></li>
<li><p>Install the serialport gem for Ruby
 gem install serialport (I used version 1.0.4)</p></li>
<li><p>Mount the scanner on top of the reader by lining up the prongs in the appropriate slot. Then plug the reader into the Mini-USB port of the mac.</p></li>
<li><p>From the console, locate the virtual com port the drivers created when you plugged in your Mini-USB cable.
 :~ ls -la /dev</p>

<p> Scanning the output from this command you should see the device listed similar to this:  cu.usbserial-XXXXXX (where X&#8217;s represent a driver id). Mine showed up as &#8220;cu.usbserial-A900ftPb&#8221; but yours may be different.</p></li>
<li><p>Use this sample code to print the unique RFID id stored inside the card, when someone swipes the card over the scanner.</p></li>
</ol>


<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="c1"># Simple example of reading from serial port to interface with the RFID reader.</span>
</span><span class='line'><span class="nb">require</span> <span class="s2">&quot;serialport&quot;</span>
</span><span class='line'><span class="k">class</span> <span class="nc">RfidReader</span>
</span><span class='line'> <span class="kp">attr_accessor</span> <span class="ss">:key</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">port</span><span class="p">)</span>
</span><span class='line'>   <span class="n">port_str</span> <span class="o">=</span> <span class="n">port</span>
</span><span class='line'>   <span class="n">baud_rate</span> <span class="o">=</span> <span class="mi">9600</span>
</span><span class='line'>   <span class="n">data_bits</span> <span class="o">=</span> <span class="mi">8</span>
</span><span class='line'>   <span class="n">stop_bits</span> <span class="o">=</span> <span class="mi">1</span>
</span><span class='line'>   <span class="n">parity</span> <span class="o">=</span> <span class="no">SerialPort</span><span class="o">::</span><span class="no">NONE</span>
</span><span class='line'>   <span class="vi">@sp</span> <span class="o">=</span> <span class="no">SerialPort</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="n">port_str</span><span class="p">,</span> <span class="n">baud_rate</span><span class="p">,</span> <span class="n">data_bits</span><span class="p">,</span> <span class="n">stop_bits</span><span class="p">,</span> <span class="n">parity</span><span class="p">)</span>
</span><span class='line'>   <span class="vi">@key_parts</span> <span class="o">=</span> <span class="o">[]</span>
</span><span class='line'>   <span class="vi">@key_limit</span> <span class="o">=</span> <span class="mi">16</span> <span class="c1"># number of slots in the RFID card.</span>
</span><span class='line'>   <span class="k">while</span> <span class="kp">true</span> <span class="k">do</span>
</span><span class='line'>     <span class="n">main</span>
</span><span class='line'>   <span class="k">end</span>
</span><span class='line'>   <span class="vi">@sp</span><span class="o">.</span><span class="n">close</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">key_detected?</span>
</span><span class='line'>   <span class="vi">@key_parts</span> <span class="o">&lt;&lt;</span> <span class="vi">@sp</span><span class="o">.</span><span class="n">getc</span>
</span><span class='line'>   <span class="k">if</span> <span class="vi">@key_parts</span><span class="o">.</span><span class="n">size</span> <span class="o">&gt;=</span> <span class="vi">@key_limit</span>
</span><span class='line'>     <span class="nb">self</span><span class="o">.</span><span class="n">key</span> <span class="o">=</span> <span class="vi">@key_parts</span><span class="o">.</span><span class="n">join</span><span class="p">()</span>
</span><span class='line'>     <span class="vi">@key_parts</span> <span class="o">=</span> <span class="o">[]</span>
</span><span class='line'>     <span class="kp">true</span>
</span><span class='line'>   <span class="k">else</span>
</span><span class='line'>     <span class="kp">false</span>
</span><span class='line'>   <span class="k">end</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'>
</span><span class='line'> <span class="k">def</span> <span class="nf">main</span>
</span><span class='line'>   <span class="k">if</span> <span class="n">key_detected?</span>
</span><span class='line'>     <span class="nb">puts</span> <span class="nb">self</span><span class="o">.</span><span class="n">key</span>
</span><span class='line'>   <span class="k">end</span>
</span><span class='line'> <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="no">RfidReader</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="s2">&quot;/dev/cu.usbserial-A900ftPb&quot;</span><span class="p">)</span>  <span class="c1">#may be different for you</span>
</span></code></pre></td></tr></table></div></figure>


<p>Once you have the unique ID the possibilities become nearly limitless, you can use the card to update twitter, or turn on your lights, turn on the coffee pot, fire the nerf guns, release the hounds etc. Have fun, I know I will!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[9 Secrets To Running A Successful Crowdfunding Campaign.]]></title>
    <link href="http://heavysixer.github.com/blog/2012/04/14/running-an-effective-campaign-on-pledgie/"/>
    <updated>2012-04-14T20:09:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/04/14/running-an-effective-campaign-on-pledgie</id>
    <content type="html"><![CDATA[<p>As many of your know, I am one of the co-founders of Pledgie. Occasionally, I get asked for advice on how to make an effective campaign on Pledgie and so I began to seriously research this topic about three months ago. Using research, expert advice and by analyzing the thousands of existing Pledgie campaigns I attempted to distill the qualities of a successful campaign into a series of tips (actually nine of them). Whether you are an individual or an organization using Pledgie to raise money, these points may help you to craft a winning message.</p>

<h2>1. Empathy Over Sympathy</h2>

<p>The job of your campaign message is to focus on the empathetic link between your cause and your donors. Instead of trying to elicit feelings of guilt or pity, focus on positive connections your donors share with your campaign.</p>

<p>Humans, like many other animals, feel empathy and sympathy for one another. Both are incredibly powerful emotions but when it comes to triggering a donor to make a commitment empathy rules the day, and here’s why.  Empathy is both the ability to logically understand the experience of others, and simultaneously share a visceral emotional link. Sympathy, however is our ability to feel sorry for someone else’s misfortune, but at a more abstract emotional level. For example, a parent might feel empathy looking at a sick child, because they can imagine their own child in a similar state. In contrast someone without kids might just feel sympathy for child without feeling the greater shared circumstance.</p>

<h2>2. Tell A Story</h2>

<p>When crafting your campaign, tell the story of your cause. People are more likely to connect with a narrative than with facts and figures. When crafting your campaign story, ask yourself if it answers these questions:
Who are you?
Why is this campaign important to you?
What problem does this campaign seek to solve?
Why is this campaign important to the donor?</p>

<h2>3. Be Yourself</h2>

<p>Donors do not contribute to an idea; they contribute to a person. When describing yourself or your organization, use simple and direct language that gives a brief and complete picture of who you are, and why your campaign is a passion worth funding. The goal is to get potential donors to start seeing you as a real person and not just words and images on a webpage.</p>

<h2>4. Don’t Forget to Ask</h2>

<p>This seems obvious, but you’d be surprised how many campaigns never ask for funds! People often think that the goal of a Pledgie campaign is to describe the need. While that is an essential component of a good campaign, the actual goal of a Pledgie campaign is to get others to do something about your need. When crafting your campaign message you should concentrate on adding language that:
Encourages potential donors to act immediately.
Gives them explicit actions they can take to help your campaign.</p>

<h2>5. Get Your Friends &amp; Supporters Involved</h2>

<p>Your friends and supporters are your base, they provide a stable foundation to build your outreach upon. When spreading your message through social networks like Twitter or Facebook, it is essential that your friends help make a personal appeal. As a message spreads across your social graph it can suffer an entropy in trust. This may happen, because as your message spreads the recipients are less likely to know you personally. Asking for personal appeals from others help, because people are more likely to give if someone they know is personally invested.</p>

<h2>6. Look for collaborators not benefactors</h2>

<p>Donors who are funding a cause want to feel like they are part of a solution, and not just performing an act of charity. Craft your message in a way that demonstrates to the donor that they are investing in the outcome, and that you will keep them up-to-date as you progress towards your goal.</p>

<h2>7. Photo Finish</h2>

<p>We cannot stress enough how important having a video or photo is when crafting your campaign. Even if the photo is just a portrait of yourself, simply having a photo or video associated with your campaign description can make a huge difference in perceived credibility.</p>

<h2>8. Follow Up With Progress Reports</h2>

<p>Donors who have donated once are likely to donate again if you ask them. Sometimes the easiest way to ask is to share your progress towards your goals. Giving periodic updates to your donor base shows them that they made a wise investment in you, and that you can be trusted with additional funds.</p>

<h2>9. Be Grateful</h2>

<p>When someone makes an effort to support your cause, be sure to say thank you.  It gives them a sense of connection and fulfillment that can lead to future support. It is also the right thing to do!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[On Jumping]]></title>
    <link href="http://heavysixer.github.com/blog/2012/04/05/on-jumping/"/>
    <updated>2012-04-05T09:39:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/04/05/on-jumping</id>
    <content type="html"><![CDATA[<blockquote><p>Jump and the net will appear.</p><footer><strong>John Burroughs</strong><cite><a href='http://en.wikipedia.org/wiki/John_Burroughs'>en.wikipedia.org/wiki/&hellip;</a></cite></footer></blockquote>


<p>Seven years ago there was much handwringing around leaving my job to start my own consultancy. That is until my friend told me this quote from John Burroughs. It is a compelling illustration about faith in yourself and that the world values you. It often resurfaces for me when I am mulling over a risky proposition. The best thing about this quote is when properly applied, if the net doesn&#8217;t appear&#8230; well it won&#8217;t hurt long!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Thoughts on Requirement Gathering]]></title>
    <link href="http://heavysixer.github.com/blog/2012/04/04/thoughts-on-requirement-docs/"/>
    <updated>2012-04-04T15:10:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/04/04/thoughts-on-requirement-docs</id>
    <content type="html"><![CDATA[<blockquote><p>Requirement documents should be a recipe not a shopping list.</p></blockquote>


<p>This metaphor is my attempt to encapsulate what a good requirements document is. Both a shopping list and a recipe are essentially lists of ingredients in various quantities. However, the recipe also includes a desired outcome and precise descriptions of how the ingredients are meant to be used.</p>

<p>When evaluating a requirement document ask yourself if it gives you a clear understanding of what it is you are being asked to build, and how the independent parts work together. If it doesn&#8217;t do that then, my friend, you are reading a shopping list.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[client-side request caching with Javascript]]></title>
    <link href="http://heavysixer.github.com/blog/2012/03/28/client-side-request-caching-with-javascript/"/>
    <updated>2012-03-28T20:30:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/03/28/client-side-request-caching-with-javascript</id>
    <content type="html"><![CDATA[<p>Recently I was writing an enterprise data visualization application that made heavy user of interactive charts and graphs. Like most best-of-breed data-viz apps this one supported very robust filters for slicing and dicing through the dataset. Each time the user adjusted one of these filters the application made new AJAX request and idled until the results were returned.</p>

<p>Technically, this approach worked fine, but because the data-segmentation occurred on the server the charts felt sluggish because they were always polling or data. Additionally, the user quite frequently toggled between only a couple filters to compare the results. What should have been an experience of rapidly flipping between two views on the data was actually a belabored rendering experience. As the developer this was frustrating because they were asking for and receiving the same data over and over again.</p>

<p>To solve this problem, I built a very simple mechanism that affords <em>just enough caching</em> to persist these payload objects only while the user is viewing the page. In this way the user would be guaranteed to get a fresh copy from the server on each page load.</p>

<p>Essentially, I hooked my caching routine around the function that made the AJAX request for new chart data. Using this approach an AJAX request only occurred once, and all future requests pulled from the cache.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// Called when someone adjusts a filter</span>
</span><span class='line'><span class="kd">function</span> <span class="nx">updateChart</span><span class="p">(</span><span class="nx">url</span><span class="p">,</span> <span class="nx">chart</span><span class="p">,</span> <span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Builds the request params needed to correctly query the server. </span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">opts</span> <span class="o">=</span> <span class="nx">requestParamsFor</span><span class="p">(</span><span class="nx">chart</span><span class="p">,</span> <span class="nx">key</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="c1">// Generate a cache key based on this object</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">cacheKey</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKey</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>    <span class="k">if</span> <span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">hh</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">exists</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>        <span class="c1">// If the key exists then the request has happened in the past</span>
</span><span class='line'>        <span class="c1">// use the cached result to refresh the chart.</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">);</span>
</span><span class='line'>        <span class="nx">onSuccess</span><span class="p">(</span><span class="nx">kind</span><span class="p">,</span> <span class="nx">opts</span><span class="p">,</span> <span class="nx">chart</span><span class="p">,</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
</span><span class='line'>    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">$</span><span class="p">.</span><span class="nx">ajax</span><span class="p">({</span>
</span><span class='line'>            <span class="nx">url</span><span class="o">:</span> <span class="nx">url</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;POST&#39;</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">data</span><span class="o">:</span> <span class="nx">opts</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">success</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">result</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>                <span class="c1">// Since this was a new request store the results in the cache </span>
</span><span class='line'>                <span class="c1">// at the location specified by the cache key.</span>
</span><span class='line'>                <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
</span><span class='line'>                <span class="nx">onSuccess</span><span class="p">(</span><span class="nx">kind</span><span class="p">,</span> <span class="nx">opts</span><span class="p">,</span> <span class="nx">chart</span><span class="p">,</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">result</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here is the local cache class in all it&#8217;s detail:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_cache</span> <span class="o">=</span> <span class="p">{};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_keys</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_indexOf</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">arr</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">arr</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">i</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">i</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nx">arr</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span> <span class="o">==</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="k">return</span> <span class="nx">i</span><span class="p">;</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="o">-</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_serialize</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">((</span><span class="nx">opts</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span> <span class="o">===</span> <span class="s2">&quot;[object Object]&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">param</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="p">(</span><span class="nx">opts</span><span class="p">).</span><span class="nx">toString</span><span class="p">();</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_remove</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">t</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">((</span><span class="nx">t</span> <span class="o">=</span> <span class="nx">_indexOf</span><span class="p">(</span><span class="nx">_keys</span><span class="p">,</span> <span class="nx">key</span><span class="p">))</span> <span class="o">&gt;</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_keys</span><span class="p">.</span><span class="nx">splice</span><span class="p">(</span><span class="nx">t</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span><span class='line'>            <span class="k">delete</span> <span class="nx">_cache</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_removeAll</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">_cache</span> <span class="o">=</span> <span class="p">{};</span>
</span><span class='line'>        <span class="nx">_keys</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">add</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nx">_keys</span><span class="p">.</span><span class="nx">indexOf</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="o">===</span> <span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_keys</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="nx">_cache</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">=</span> <span class="nx">obj</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">hh</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">exists</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">_cache</span><span class="p">.</span><span class="nx">hasOwnProperty</span><span class="p">(</span><span class="nx">key</span><span class="p">);</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">purge</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nx">arguments</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_remove</span><span class="p">(</span><span class="nx">arguments</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_removeAll</span><span class="p">();</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">$</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="p">{},</span>
</span><span class='line'>        <span class="nx">_cache</span><span class="p">);</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">searchKeys</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">str</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">keys</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">rStr</span><span class="p">;</span>
</span><span class='line'>        <span class="nx">rStr</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">RegExp</span><span class="p">(</span><span class="s1">&#39;\\b&#39;</span> <span class="o">+</span> <span class="nx">str</span> <span class="o">+</span> <span class="s1">&#39;\\b&#39;</span><span class="p">,</span> <span class="s1">&#39;i&#39;</span><span class="p">);</span>
</span><span class='line'>        <span class="nx">$</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">_keys</span><span class="p">,</span>
</span><span class='line'>        <span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="nx">rStr</span><span class="p">))</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">keys</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">e</span><span class="p">);</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">});</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">keys</span><span class="p">;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">get</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">val</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="nx">_cache</span><span class="p">[</span><span class="nx">key</span><span class="p">]</span> <span class="o">!==</span> <span class="kc">undefined</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">if</span> <span class="p">((</span><span class="nx">_cache</span><span class="p">[</span><span class="nx">key</span><span class="p">]).</span><span class="nx">toString</span><span class="p">()</span> <span class="o">===</span> <span class="s2">&quot;[object Object]&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">val</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">extend</span><span class="p">(</span><span class="kc">true</span><span class="p">,</span> <span class="p">{},</span>
</span><span class='line'>                <span class="nx">_cache</span><span class="p">[</span><span class="nx">key</span><span class="p">]);</span>
</span><span class='line'>            <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">val</span> <span class="o">=</span> <span class="nx">_cache</span><span class="p">[</span><span class="nx">key</span><span class="p">];</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">val</span><span class="p">;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">getKey</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">_serialize</span><span class="p">(</span><span class="nx">opts</span><span class="p">);</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">getKeys</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">_keys</span><span class="p">;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">add</span><span class="o">:</span> <span class="nx">add</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">exists</span><span class="o">:</span> <span class="nx">exists</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">purge</span><span class="o">:</span> <span class="nx">purge</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">searchKeys</span><span class="o">:</span> <span class="nx">searchKeys</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">get</span><span class="o">:</span> <span class="nx">get</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">getKey</span><span class="o">:</span> <span class="nx">getKey</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">getKeys</span><span class="o">:</span> <span class="nx">getKeys</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'><span class="p">}).</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here are some jasmine tests which explain more features of the cache not covered in this post, and prove that it works!</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should allow you to build a cache using keys&quot;</span><span class="p">,</span>
</span><span class='line'><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>        <span class="s1">&#39;foo&#39;</span><span class="o">:</span> <span class="s1">&#39;bar&#39;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">exists</span><span class="p">(</span><span class="s2">&quot;foo=bar&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKey</span><span class="p">(</span><span class="nx">obj</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;foo=bar&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKey</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s2">&quot;foo=bar&quot;</span><span class="p">,</span> <span class="nx">obj</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">exists</span><span class="p">(</span><span class="s2">&quot;foo=bar&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;foo=bar&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">obj</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s2">&quot;bar&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="kc">undefined</span><span class="p">);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should allow you to empty the cache completely&quot;</span><span class="p">,</span>
</span><span class='line'><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">purge</span><span class="p">();</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s2">&quot;baz&quot;</span><span class="p">,</span> <span class="s1">&#39;baz&#39;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;baz&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKeys</span><span class="p">().</span><span class="nx">length</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">purge</span><span class="p">()).</span><span class="nx">toEqual</span><span class="p">({});</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should allow you to empty the cache of just a specific record&quot;</span><span class="p">,</span>
</span><span class='line'><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">purge</span><span class="p">();</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s2">&quot;baz&quot;</span><span class="p">,</span> <span class="s1">&#39;baz&#39;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;baz&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s2">&quot;boff&quot;</span><span class="p">,</span> <span class="s1">&#39;ball&#39;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">(</span><span class="s1">&#39;ball&#39;</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKeys</span><span class="p">()).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s1">&#39;baz&#39;</span><span class="p">,</span> <span class="s1">&#39;boff&#39;</span><span class="p">]);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">purge</span><span class="p">(</span><span class="s1">&#39;boff&#39;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">({</span>
</span><span class='line'>        <span class="s1">&#39;baz&#39;</span><span class="o">:</span> <span class="s1">&#39;baz&#39;</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKeys</span><span class="p">()).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s1">&#39;baz&#39;</span><span class="p">]);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">purge</span><span class="p">(</span><span class="s1">&#39;bozz&#39;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">({</span>
</span><span class='line'>        <span class="s1">&#39;baz&#39;</span><span class="o">:</span> <span class="s1">&#39;baz&#39;</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKeys</span><span class="p">()).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s1">&#39;baz&#39;</span><span class="p">]);</span>
</span><span class='line'><span class="p">});</span>
</span><span class='line'>
</span><span class='line'><span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should allow you to search for keys in the cache&quot;</span><span class="p">,</span>
</span><span class='line'><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">purge</span><span class="p">();</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">obj</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>        <span class="s1">&#39;bar&#39;</span><span class="o">:</span> <span class="s1">&#39;baz&#39;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">add</span><span class="p">(</span><span class="s1">&#39;bar=baz&#39;</span><span class="p">,</span> <span class="nx">obj</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKeys</span><span class="p">().</span><span class="nx">length</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">getKeys</span><span class="p">()).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s2">&quot;bar=baz&quot;</span><span class="p">]);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">searchKeys</span><span class="p">(</span><span class="s2">&quot;bar&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s2">&quot;bar=baz&quot;</span><span class="p">]);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">searchKeys</span><span class="p">(</span><span class="s2">&quot;bar=&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s2">&quot;bar=baz&quot;</span><span class="p">]);</span>
</span><span class='line'>    <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">cache</span><span class="p">.</span><span class="nx">searchKeys</span><span class="p">(</span><span class="s2">&quot;bat&quot;</span><span class="p">)).</span><span class="nx">toEqual</span><span class="p">([]);</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rails Protip: hash.slice]]></title>
    <link href="http://heavysixer.github.com/blog/2012/03/26/rails-protip-hash-dot-slice/"/>
    <updated>2012-03-26T11:09:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/03/26/rails-protip-hash-dot-slice</id>
    <content type="html"><![CDATA[<p>Rails has hidden gems just waiting to be discovered. I will demonstrate the use of <em>Hash.slice</em>, which is one of the core extensions of ActiveSupport.</p>

<p>Here is an example of how <em>Hash.slice</em> can clean up a controller, take this existing code for example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">index</span>
</span><span class='line'>  <span class="vi">@users</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">paginate</span><span class="p">({</span> <span class="ss">:page</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:page</span><span class="o">].</span><span class="n">present?</span> <span class="p">?</span> <span class="n">params</span><span class="o">[</span><span class="ss">:page</span><span class="o">].</span><span class="n">to_i</span> <span class="p">:</span> <span class="mi">1</span><span class="p">,</span> <span class="ss">:per_page</span> <span class="o">=&gt;</span> <span class="n">params</span><span class="o">[</span><span class="ss">:per_page</span><span class="o">].</span><span class="n">present?</span> <span class="p">?</span> <span class="n">params</span><span class="o">[</span><span class="ss">:per_page</span><span class="o">].</span><span class="n">to_i</span> <span class="p">:</span> <span class="mi">12</span> <span class="p">})</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>With <em>Hash.slice</em> we can shorten it to:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">def</span> <span class="nf">index</span>
</span><span class='line'>  <span class="vi">@users</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">paginate</span><span class="p">({</span> <span class="ss">:page</span> <span class="o">=&gt;</span> <span class="mi">1</span><span class="p">,</span> <span class="ss">:per_page</span> <span class="o">=&gt;</span> <span class="mi">12</span> <span class="p">}</span><span class="o">.</span><span class="n">merge</span><span class="p">(</span><span class="n">params</span><span class="o">.</span><span class="n">slice</span><span class="p">(</span><span class="ss">:page</span><span class="p">,</span> <span class="ss">:per_page</span><span class="p">)))</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p><em>Hash.slice</em> is that it is very forgiving. The method only returns the attributes if they exist. In our example we are assured all conditions will be met because the default values will only be overwritten if <em>Hash.slice</em> returns them.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Minimally Viable Party]]></title>
    <link href="http://heavysixer.github.com/blog/2012/03/25/the-minimally-viable-party/"/>
    <updated>2012-03-25T15:50:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/03/25/the-minimally-viable-party</id>
    <content type="html"><![CDATA[<p>Garry and I are planning our next big project together. In the spirit of agile development and with the reality of limited funds we are ruthlessly scoping our efforts around a minimal feature set. We want to develop just enough of the product to see if we have a hit. Typically, this process is described as developing the minimum viable product (MVP).</p>

<p>The MVP approach targets the hardcore vocal minority that understand your offering, and are likely to give you helpful insights on how to improve it. With this in mind we began to list our potential features and aggressively cut anything that wasn’t essential.</p>

<p>We tried a variety of approaches to identify our MVP. Which included:</p>

<ul>
<li>Sorting features in order of complexity, and identifying those with serial dependencies</li>
<li>Selecting only those features that touch the revenue line (a topic for another post)</li>
<li>Determining those features which could give us a competitive advantage over other similar products.</li>
</ul>


<p>These thought experiments were helpful, but the focus felt very myopic, and more about cutting than pruning; like shaping a bonsai tree blindfolded. However, while mowing the lawn (where I do much of my good thinking), I came up with a new approach: “The Minimum Viable Party”.</p>

<p>A party seemed like a perfect metaphor for these reasons:</p>

<ul>
<li>The goal of product at this stage, is to meet people, show them a good time and give them a complete experience they can give feedback on.</li>
<li>Parties are events with a specific beginnings and ends. Being the host narrows your responsibilities to just throwing a great party. If you find yourself needing to first build the venue, or starting a catering company at the same time then <em>you are doing it wrong</em>.</li>
<li>Parties are fun, (even Goth Emo parties); they are about doing something you love, with others looking for the same thing.</li>
<li>A complete party is more than just good food. There are many aspects that can be considered including venue, theme, duration, etc.</li>
<li>If it all goes horribly wrong you can recover. You just clean up the mess, pull the lawn chairs off the roof, get a tow company to dredge your car from the neighbors pool and go on with your life.</li>
<li>By breaking a party into smaller components you can map them onto the MVP. Now, I am not for a minute claiming that there is an absolute one-to-one mapping between party to product. However, the metaphor did allow me to consider the attributes of my product in a more objective and holistic way. For example, a decision on whether to spend money on party invitations could be construed as a marketing spend on promoting our product.</li>
</ul>


<h2>Planning a Minimal Viable Party</h2>

<p>Here are the rules for the Minimal Viable Party thought experiment:</p>

<ul>
<li>You are planning a party for people you do not know.</li>
<li>You have one week to plan and execute your party.</li>
<li>Without specifying a specific amount you should assume that funds are very limited, which should force you to make decisions on how and where to spend your money.</li>
<li>The party is not a catered meaning that much if not all the work should be done personally.</li>
</ul>


<p>These rules lead me to a series of questions to consider which i’ve detailed below:</p>

<p><strong>Q.</strong> How many guests should I invite?</p>

<p><strong>A.</strong> You should invite the number of guests you can host comfortably. Everyone wants to feel special at the party, meaning you should know your limits before the inviting others.</p>

<p><strong>Insight:</strong> Many people focus on the hockey stick style growth from the outset, that is a result of a good product not the goal itself. At this stage the goal is to get to know the users, and the only way to do that is to ensure there is enough of you to go around.</p>

<p><strong>Q.</strong> How do I entertain people I have never met?</p>

<p><strong>A.</strong> Plan a party around the type of guest you’d want to see again. If you are a geek at heart then have your party on the holodeck and don’t mind the haters.</p>

<p><strong>Insight:</strong> You can’t please everyone but it’s important that you understand who you’d like as customers and friends. Ensure that your product gives them a memorable and enjoyable experience.</p>

<p><strong>Q.</strong> What kind of food should I cook?</p>

<p><strong>A.</strong> Be honest about your own cooking skills, anything you don’t do well you should either eliminate or buy (even if this means you have to buy all the food).</p>

<p><strong>Insight:</strong> No one wants to eat bad food, a strangers will not give you an “A” for effort when eating your half-cooked hamburgers. The same is true for a poorly executed product. I continually have to fight the urge to be an <em>everything expert</em>. While striving to learn new things is a positive, not knowing (or ignoring) your weaknesses limits you from being effective under a deadline.</p>

<p><strong>Q.</strong> How many courses should I prepare?</p>

<p><strong>A.</strong> What would your ideal guest expect? Not everyone expets (or even wants) a five course meal that takes hours to eat. What they will want is for it to feel complete, and that differs from person to person.</p>

<p><strong>Insight:</strong> The expression “soup to nuts” is often used when describing a project completed from beginning to end. It alludes to a complete meal that included appetizers (soup), nuts (dessert) and everything in between. If you view your features through the lens of completeness it should help you determine if a feature is needed now or can wait.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Generate Beautiful Gradients Using Javascript]]></title>
    <link href="http://heavysixer.github.com/blog/2012/03/23/generate-beautiful-gradients-using-javascript/"/>
    <updated>2012-03-23T10:34:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/03/23/generate-beautiful-gradients-using-javascript</id>
    <content type="html"><![CDATA[<p>I use Highcharts an excellent charting library built in Javascript for much of my data visualization and analytic work. However, one thing that has always bugged me is their collection of default series colors, which are a bit limp. Highcharts does provide an easy way to manually override their defaults with your own list of colors. Unfortunately, it&#8217;s not always possible to know in advance how many series will be supplied to the chart object. In the cases where there are more series than there are manually supplied colors the Highcharts default colors will start to leak into your charts and ruin the visual aesthetics. I wrote the gradient generator to produce a range of colors based on the parameters you supply. You simply supply start and stop colors and the number of steps in between, and you&#8217;ll be sure to have enough colors for your series.</p>

<p>Even though I made this generator for a need I had in highcharts, you can use it anywhere you want a uniform sequence of colors. Here is how I use it in Highcharts:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="kd">var</span> <span class="nx">seriesColors</span> <span class="o">=</span> <span class="nx">gradientFactory</span><span class="p">.</span><span class="nx">generate</span><span class="p">({</span>
</span><span class='line'>    <span class="nx">from</span><span class="o">:</span> <span class="s2">&quot;#0000FF&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nx">to</span><span class="o">:</span> <span class="s2">&quot;&quot;</span><span class="err">#</span><span class="nx">FF0000</span><span class="err">&quot;</span>
</span><span class='line'>    <span class="nx">stops</span><span class="o">:</span> <span class="nx">chartConfig</span><span class="p">.</span><span class="nx">series</span><span class="p">.</span><span class="nx">length</span>
</span><span class='line'><span class="p">})</span>
</span><span class='line'><span class="nx">$</span><span class="p">.</span><span class="nx">each</span><span class="p">(</span><span class="nx">chartConfig</span><span class="p">.</span><span class="nx">series</span><span class="p">,</span>
</span><span class='line'><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">v</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>    <span class="nx">seriesOptions</span><span class="p">.</span><span class="nx">push</span><span class="p">({</span>
</span><span class='line'>        <span class="nx">color</span><span class="o">:</span> <span class="nx">seriesColors</span><span class="p">[</span><span class="nx">i</span><span class="p">]</span>
</span><span class='line'>        <span class="c1">// other attributes ...</span>
</span><span class='line'>    <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here is the code for the Gradient Factory:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">gradientFactory</span> <span class="o">=</span> <span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_beginColor</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">red</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">green</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">blue</span><span class="o">:</span> <span class="mi">0</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_endColor</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">red</span><span class="o">:</span> <span class="mi">255</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">green</span><span class="o">:</span> <span class="mi">255</span><span class="p">,</span>
</span><span class='line'>        <span class="nx">blue</span><span class="o">:</span> <span class="mi">255</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_colorStops</span> <span class="o">=</span> <span class="mi">24</span><span class="p">;</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_colors</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_colorKeys</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;red&#39;</span><span class="p">,</span> <span class="s1">&#39;green&#39;</span><span class="p">,</span> <span class="s1">&#39;blue&#39;</span><span class="p">];</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_rgbToHex</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">r</span><span class="p">,</span> <span class="nx">g</span><span class="p">,</span> <span class="nx">b</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">return</span> <span class="s1">&#39;#&#39;</span> <span class="o">+</span> <span class="nx">_byteToHex</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="o">+</span> <span class="nx">_byteToHex</span><span class="p">(</span><span class="nx">g</span><span class="p">)</span> <span class="o">+</span> <span class="nx">_byteToHex</span><span class="p">(</span><span class="nx">b</span><span class="p">);</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_byteToHex</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">n</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">hexVals</span> <span class="o">=</span> <span class="s2">&quot;0123456789ABCDEF&quot;</span><span class="p">;</span>
</span><span class='line'>        <span class="k">return</span> <span class="nb">String</span><span class="p">(</span><span class="nx">hexVals</span><span class="p">.</span><span class="nx">substr</span><span class="p">((</span><span class="nx">n</span> <span class="o">&gt;&gt;</span> <span class="mi">4</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x0F</span><span class="p">,</span> <span class="mi">1</span><span class="p">))</span> <span class="o">+</span> <span class="nx">hexVals</span><span class="p">.</span><span class="nx">substr</span><span class="p">(</span><span class="nx">n</span> <span class="o">&amp;</span> <span class="mh">0x0F</span><span class="p">,</span> <span class="mi">1</span><span class="p">);</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_parseColor</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">color</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">((</span><span class="nx">color</span><span class="p">).</span><span class="nx">toString</span><span class="p">()</span> <span class="o">===</span> <span class="s2">&quot;[object Object]&quot;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="k">return</span> <span class="nx">color</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">color</span> <span class="o">=</span> <span class="p">(</span><span class="nx">color</span><span class="p">.</span><span class="nx">charAt</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span> <span class="o">==</span> <span class="s2">&quot;#&quot;</span><span class="p">)</span> <span class="o">?</span> <span class="nx">color</span><span class="p">.</span><span class="nx">substring</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">7</span><span class="p">)</span> <span class="o">:</span> <span class="nx">color</span><span class="p">;</span>
</span><span class='line'>            <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">red</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">((</span><span class="nx">color</span><span class="p">).</span><span class="nx">substring</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="mi">2</span><span class="p">),</span> <span class="mi">16</span><span class="p">),</span>
</span><span class='line'>                <span class="nx">green</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">((</span><span class="nx">color</span><span class="p">).</span><span class="nx">substring</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">),</span> <span class="mi">16</span><span class="p">),</span>
</span><span class='line'>                <span class="nx">blue</span><span class="o">:</span> <span class="nb">parseInt</span><span class="p">((</span><span class="nx">color</span><span class="p">).</span><span class="nx">substring</span><span class="p">(</span><span class="mi">4</span><span class="p">,</span> <span class="mi">6</span><span class="p">),</span> <span class="mi">16</span><span class="p">)</span>
</span><span class='line'>            <span class="p">};</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="kd">var</span> <span class="nx">_generate</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">opts</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">_colors</span> <span class="o">=</span> <span class="p">[];</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">options</span> <span class="o">=</span> <span class="nx">opts</span> <span class="o">||</span> <span class="p">{};</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">diff</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">red</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">green</span><span class="o">:</span> <span class="mi">0</span><span class="p">,</span>
</span><span class='line'>            <span class="nx">blue</span><span class="o">:</span> <span class="mi">0</span>
</span><span class='line'>        <span class="p">};</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">len</span> <span class="o">=</span> <span class="nx">_colorKeys</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
</span><span class='line'>        <span class="kd">var</span> <span class="nx">pOffset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">from</span><span class="p">)</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_beginColor</span> <span class="o">=</span> <span class="nx">_parseColor</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">from</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">to</span><span class="p">)</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_endColor</span> <span class="o">=</span> <span class="nx">_parseColor</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">to</span><span class="p">);</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="nx">options</span><span class="p">.</span><span class="nx">stops</span><span class="p">)</span> <span class="o">!==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">_colorStops</span> <span class="o">=</span> <span class="nx">options</span><span class="p">.</span><span class="nx">stops</span><span class="p">;</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="nx">_colorStops</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="nx">_colorStops</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
</span><span class='line'>        <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">x</span> <span class="o">&lt;</span> <span class="nx">_colorStops</span><span class="p">;</span> <span class="nx">x</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>            <span class="nx">pOffset</span> <span class="o">=</span> <span class="nb">parseFloat</span><span class="p">(</span><span class="nx">x</span><span class="p">,</span> <span class="mi">10</span><span class="p">)</span> <span class="o">/</span> <span class="nx">_colorStops</span><span class="p">;</span>
</span><span class='line'>            <span class="k">for</span> <span class="p">(</span><span class="kd">var</span> <span class="nx">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="nx">y</span> <span class="o">&lt;</span> <span class="nx">len</span><span class="p">;</span> <span class="nx">y</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'>                <span class="nx">diff</span><span class="p">[</span><span class="nx">_colorKeys</span><span class="p">[</span><span class="nx">y</span><span class="p">]]</span> <span class="o">=</span> <span class="nx">_endColor</span><span class="p">[</span><span class="nx">_colorKeys</span><span class="p">[</span><span class="nx">y</span><span class="p">]]</span> <span class="o">-</span> <span class="nx">_beginColor</span><span class="p">[</span><span class="nx">_colorKeys</span><span class="p">[</span><span class="nx">y</span><span class="p">]];</span>
</span><span class='line'>                <span class="nx">diff</span><span class="p">[</span><span class="nx">_colorKeys</span><span class="p">[</span><span class="nx">y</span><span class="p">]]</span> <span class="o">=</span> <span class="p">(</span><span class="nx">diff</span><span class="p">[</span><span class="nx">_colorKeys</span><span class="p">[</span><span class="nx">y</span><span class="p">]]</span> <span class="o">*</span> <span class="nx">pOffset</span><span class="p">)</span> <span class="o">+</span> <span class="nx">_beginColor</span><span class="p">[</span><span class="nx">_colorKeys</span><span class="p">[</span><span class="nx">y</span><span class="p">]];</span>
</span><span class='line'>            <span class="p">}</span>
</span><span class='line'>            <span class="nx">_colors</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">_rgbToHex</span><span class="p">(</span><span class="nx">diff</span><span class="p">.</span><span class="nx">red</span><span class="p">,</span> <span class="nx">diff</span><span class="p">.</span><span class="nx">green</span><span class="p">,</span> <span class="nx">diff</span><span class="p">.</span><span class="nx">blue</span><span class="p">));</span>
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>        <span class="nx">_colors</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">_rgbToHex</span><span class="p">(</span><span class="nx">_endColor</span><span class="p">.</span><span class="nx">red</span><span class="p">,</span> <span class="nx">_endColor</span><span class="p">.</span><span class="nx">green</span><span class="p">,</span> <span class="nx">_endColor</span><span class="p">.</span><span class="nx">blue</span><span class="p">));</span>
</span><span class='line'>        <span class="k">return</span> <span class="nx">_colors</span><span class="p">;</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'>    <span class="k">return</span> <span class="p">{</span>
</span><span class='line'>        <span class="nx">generate</span><span class="o">:</span> <span class="nx">_generate</span>
</span><span class='line'>    <span class="p">};</span>
</span><span class='line'><span class="p">}).</span><span class="nx">call</span><span class="p">(</span><span class="k">this</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here are a few Jasmine Specs to prove it works:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="nx">describe</span><span class="p">(</span><span class="s2">&quot;Gradient Generator&quot;</span><span class="p">,</span>
</span><span class='line'><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>  <span class="nx">it</span><span class="p">(</span><span class="s2">&quot;should generate a series of gradient colors&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'>      <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">hh</span><span class="p">.</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">gradientFactory</span><span class="p">.</span><span class="nx">generate</span><span class="p">({</span>
</span><span class='line'>          <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;#aed0ee&#39;</span><span class="p">,</span>
</span><span class='line'>          <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;#2a5980&#39;</span><span class="p">,</span>
</span><span class='line'>          <span class="nx">stops</span><span class="o">:</span> <span class="mi">2</span>
</span><span class='line'>      <span class="p">})).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s1">&#39;#AED0EE&#39;</span><span class="p">,</span> <span class="s1">&#39;#2A5980&#39;</span><span class="p">]);</span>
</span><span class='line'>      <span class="nx">expect</span><span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">hh</span><span class="p">.</span><span class="nx">plugins</span><span class="p">.</span><span class="nx">gradientFactory</span><span class="p">.</span><span class="nx">generate</span><span class="p">({</span>
</span><span class='line'>          <span class="nx">from</span><span class="o">:</span> <span class="s1">&#39;#000000&#39;</span><span class="p">,</span>
</span><span class='line'>          <span class="nx">to</span><span class="o">:</span> <span class="s1">&#39;#999999&#39;</span><span class="p">,</span>
</span><span class='line'>          <span class="nx">stops</span><span class="o">:</span> <span class="mi">10</span>
</span><span class='line'>      <span class="p">})).</span><span class="nx">toEqual</span><span class="p">([</span><span class="s1">&#39;#000000&#39;</span><span class="p">,</span> <span class="s1">&#39;#111111&#39;</span><span class="p">,</span> <span class="s1">&#39;#222222&#39;</span><span class="p">,</span> <span class="s1">&#39;#333333&#39;</span><span class="p">,</span> <span class="s1">&#39;#444444&#39;</span><span class="p">,</span> <span class="s1">&#39;#555555&#39;</span><span class="p">,</span> <span class="s1">&#39;#666666&#39;</span><span class="p">,</span> <span class="s1">&#39;#777777&#39;</span><span class="p">,</span> <span class="s1">&#39;#888888&#39;</span><span class="p">,</span> <span class="s1">&#39;#999999&#39;</span><span class="p">]);</span>
</span><span class='line'>  <span class="p">});</span>
</span><span class='line'><span class="p">});</span>
</span></code></pre></td></tr></table></div></figure>


<p>A big tip of the hat to my friend jim bumgardner, who i <a href="http://krazydad.com/tutorials/makecolors.php">cribbed the color conversation functions from</a>.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Enterprise Quality Login Validation For Rails 3]]></title>
    <link href="http://heavysixer.github.com/blog/2012/03/23/enterprise-quality-login-validation-for-rails-3/"/>
    <updated>2012-03-23T09:33:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/03/23/enterprise-quality-login-validation-for-rails-3</id>
    <content type="html"><![CDATA[<p>In the world of enterprise software development sometimes you need to be a little more thorough with your validations than you would for other types of clients. Here is a simple yet effective login validator that passes the typical forms of penetration testing you will find in the enterprise world.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">LoginFormatValidator</span> <span class="o">&lt;</span> <span class="no">ActiveModel</span><span class="o">::</span><span class="no">EachValidator</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">validate_each</span><span class="p">(</span><span class="n">object</span><span class="p">,</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">value</span><span class="o">.</span><span class="n">present?</span>
</span><span class='line'>      <span class="k">unless</span> <span class="n">value</span><span class="o">.</span><span class="n">gsub</span><span class="p">(</span><span class="s2">&quot; &quot;</span><span class="p">,</span><span class="s1">&#39;&#39;</span><span class="p">)</span> <span class="o">==</span> <span class="n">value</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;cannot contain any whitespace&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="k">if</span> <span class="o">[</span><span class="n">value</span><span class="o">[</span><span class="mi">0</span><span class="o">]</span><span class="p">,</span> <span class="n">value</span><span class="o">[-</span><span class="mi">1</span><span class="o">]].</span><span class="n">any?</span><span class="p">{</span> <span class="o">|</span><span class="n">x</span><span class="o">|</span> <span class="n">x</span> <span class="o">==</span> <span class="s2">&quot;.&quot;</span> <span class="p">}</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;cannot contain a period at the start or end&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="k">unless</span> <span class="n">value</span> <span class="o">=~</span> <span class="sr">/[a-zA-Z]/</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;must contain at least one letter&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="k">unless</span> <span class="n">value</span> <span class="o">=~</span> <span class="sr">/[0-9]/</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;must contain at least one number&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="k">unless</span> <span class="n">value</span> <span class="o">=~</span> <span class="sr">/[_\-.]/</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;must contain at least one these special characters </span><span class="se">\&quot;</span><span class="s2">-_.</span><span class="se">\&quot;</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>      <span class="k">unless</span> <span class="n">value</span> <span class="o">=~</span> <span class="sr">/^[a-zA-Z0-9_\-.]+$/</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;can only contain letters number and special these special characters </span><span class="se">\&quot;</span><span class="s2">-_.</span><span class="se">\&quot;</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can use it this way:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">validates</span> <span class="ss">:login</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:login_format</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:uniqueness</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:case_sensitive</span> <span class="o">=&gt;</span> <span class="kp">false</span> <span class="p">},</span> <span class="ss">:length</span> <span class="o">=&gt;</span> <span class="p">{</span> <span class="ss">:maximum</span> <span class="o">=&gt;</span> <span class="mi">64</span><span class="p">,</span> <span class="ss">:minimum</span> <span class="o">=&gt;</span> <span class="mi">6</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here are some specs to prove it works:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">it</span> <span class="s2">&quot;should only allow letters numbers and spaces in the name attribute&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="o">[</span><span class="s1">&#39;foo&#39;</span><span class="p">,</span> <span class="s1">&#39;foo bar baz&#39;</span><span class="p">,</span> <span class="s1">&#39;foo 123 - bar baz&#39;</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">n</span><span class="o">|</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="n">n</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:name</span><span class="o">].</span><span class="n">should</span> <span class="n">be_empty</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">name</span> <span class="o">=</span> <span class="s1">&#39;&lt;script&gt;alert(&quot;test&quot;);&lt;/script&gt;&#39;</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:name</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;is invalid&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">it</span> <span class="s2">&quot;should not allow you to change an email for an existing record&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">email</span> <span class="o">=</span> <span class="s2">&quot;test@test.com&quot;</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:email</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;cannot be changed once assigned&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">it</span> <span class="s2">&quot;should be case insenitive&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user2</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="ss">:user</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">login</span> <span class="o">=</span> <span class="vi">@user</span><span class="o">.</span><span class="n">login</span><span class="o">.</span><span class="n">capitalize</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;has already been taken&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">it</span> <span class="s2">&quot;should be at least 6 characters and no more than 64 characters&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user2</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="ss">:user</span><span class="p">,</span> <span class="ss">:login</span> <span class="o">=&gt;</span> <span class="s1">&#39;a1_&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;is too short (minimum is 6 characters)&quot;</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">login</span> <span class="o">=</span> <span class="s1">&#39;Pneumonoultramicroscopicsilicovolcanoconiosis1_is_a_very_long_word&#39;</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;is too long (maximum is 64 characters)&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">it</span> <span class="s2">&quot;should ensure the name is a mix of alpha chars (A-Z or a-z), numeric chars (0-9), and special characters (- _ .)&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user2</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="ss">:user</span><span class="p">,</span> <span class="ss">:login</span> <span class="o">=&gt;</span> <span class="s1">&#39;1----.----1&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;must contain at least one letter&quot;</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">login</span> <span class="o">=</span> <span class="s2">&quot;a------------------a&quot;</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;must contain at least one number&quot;</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">login</span> <span class="o">=</span><span class="s2">&quot;abc12345676789&quot;</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user2</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;must contain at least one these special characters </span><span class="se">\&quot;</span><span class="s2">-_.</span><span class="se">\&quot;</span><span class="s2">&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">it</span> <span class="s2">&quot;should ensure the special character &#39;.&#39; is not used at the beginning and end&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="ss">:user</span><span class="p">,</span> <span class="ss">:login</span> <span class="o">=&gt;</span> <span class="s1">&#39;.Admin_f00&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;cannot contain a period at the start or end&quot;</span>
</span><span class='line'>  <span class="vi">@user</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="ss">:user</span><span class="p">,</span> <span class="ss">:login</span> <span class="o">=&gt;</span> <span class="s1">&#39;Admin_f00.&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;cannot contain a period at the start or end&quot;</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">it</span> <span class="s2">&quot;should not allow white space or \ / </span><span class="se">\&quot;</span><span class="s2"> [ ] : | &lt; &gt; + = ; , ? * @&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user</span> <span class="o">=</span> <span class="no">Factory</span><span class="o">.</span><span class="n">build</span><span class="p">(</span><span class="ss">:user</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">login</span> <span class="o">=</span> <span class="s2">&quot;user _1&quot;</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;cannot contain any whitespace&quot;</span>
</span><span class='line'>  <span class="o">[</span><span class="s2">&quot;</span><span class="se">\\</span><span class="s2">&quot;</span><span class="p">,</span> <span class="s1">&#39;/&#39;</span><span class="p">,</span> <span class="s1">&#39;&quot;&#39;</span><span class="p">,</span> <span class="s1">&#39;[&#39;</span><span class="p">,</span> <span class="s1">&#39;]&#39;</span><span class="p">,</span> <span class="s1">&#39;:&#39;</span><span class="p">,</span> <span class="s1">&#39;|&#39;</span><span class="p">,</span> <span class="s1">&#39;&lt;&#39;</span><span class="p">,</span> <span class="s1">&#39;&gt;&#39;</span><span class="p">,</span> <span class="s1">&#39;+&#39;</span><span class="p">,</span> <span class="s1">&#39;=&#39;</span><span class="p">,</span> <span class="s1">&#39;;&#39;</span><span class="p">,</span> <span class="s1">&#39;,&#39;</span><span class="p">,</span> <span class="s1">&#39;?&#39;</span><span class="p">,</span> <span class="s1">&#39;*&#39;</span><span class="p">,</span> <span class="s1">&#39;@&#39;</span><span class="p">,</span> <span class="s2">&quot;&#39;&quot;</span><span class="o">].</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">char</span><span class="o">|</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">login</span> <span class="o">=</span> <span class="s2">&quot;user_1&quot;</span> <span class="o">&lt;&lt;</span> <span class="n">char</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>    <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:login</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;can only contain letters number and special these special characters </span><span class="se">\&quot;</span><span class="s2">-_.</span><span class="se">\&quot;</span><span class="s2">&quot;</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Simple Rails 3 Validator for Unchangeable Attributes]]></title>
    <link href="http://heavysixer.github.com/blog/2012/03/23/simple-rails-3-validator-for-unchangeable-attributes/"/>
    <updated>2012-03-23T09:23:00-05:00</updated>
    <id>http://heavysixer.github.com/blog/2012/03/23/simple-rails-3-validator-for-unchangeable-attributes</id>
    <content type="html"><![CDATA[<p>Here is a simple Rails validator that you can use to ensure an attribute of a model cannot be changed once it has been assigned a value.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">UnchangeableValidator</span> <span class="o">&lt;</span> <span class="no">ActiveModel</span><span class="o">::</span><span class="no">EachValidator</span>
</span><span class='line'>  <span class="k">def</span> <span class="nf">validate_each</span><span class="p">(</span><span class="n">object</span><span class="p">,</span> <span class="n">attribute</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</span><span class='line'>    <span class="k">if</span> <span class="o">!</span><span class="n">object</span><span class="o">.</span><span class="n">new_record?</span> <span class="o">&amp;&amp;</span> <span class="n">value</span><span class="o">.</span><span class="n">present?</span>
</span><span class='line'>      <span class="n">original</span> <span class="o">=</span> <span class="n">object</span><span class="o">.</span><span class="n">class</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="ss">:where</span><span class="p">,</span> <span class="s2">&quot;id = </span><span class="si">#{</span><span class="n">object</span><span class="o">.</span><span class="n">id</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">select</span><span class="p">(</span><span class="s2">&quot;id, </span><span class="si">#{</span><span class="n">attribute</span><span class="o">.</span><span class="n">to_s</span><span class="si">}</span><span class="s2">&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">first</span>
</span><span class='line'>      <span class="k">if</span> <span class="n">original</span><span class="o">.</span><span class="n">send</span><span class="p">(</span><span class="n">attribute</span><span class="p">)</span> <span class="o">!=</span> <span class="n">value</span>
</span><span class='line'>        <span class="n">object</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="n">attribute</span><span class="o">]</span> <span class="o">&lt;&lt;</span> <span class="p">(</span><span class="n">options</span><span class="o">[</span><span class="ss">:message</span><span class="o">]</span> <span class="o">||</span> <span class="s2">&quot;cannot be changed once assigned&quot;</span><span class="p">)</span>
</span><span class='line'>      <span class="k">end</span>
</span><span class='line'>    <span class="k">end</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>You can use it this way:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">validates</span> <span class="ss">:email</span><span class="p">,</span> <span class="ss">:unchangeable</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">,</span> <span class="ss">:presence</span> <span class="o">=&gt;</span> <span class="kp">true</span>
</span></code></pre></td></tr></table></div></figure>


<p>Here are some specs to prove it works:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">it</span> <span class="s2">&quot;should not allow you to change an email for an existing record&quot;</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">email</span> <span class="o">=</span> <span class="s2">&quot;test@test.com&quot;</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">save</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">errors</span><span class="o">[</span><span class="ss">:email</span><span class="o">].</span><span class="n">first</span><span class="o">.</span><span class="n">should</span> <span class="o">==</span> <span class="s2">&quot;cannot be changed once assigned&quot;</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Introducing ActsAsModerated]]></title>
    <link href="http://heavysixer.github.com/blog/2011/12/16/introducing-acts-as-moderated/"/>
    <updated>2011-12-16T09:06:00-06:00</updated>
    <id>http://heavysixer.github.com/blog/2011/12/16/introducing-acts-as-moderated</id>
    <content type="html"><![CDATA[<p>Periodically sites that incorporate user generated content need a way to moderate the incoming stream before publishing it to the site. Typically this is accomplished by putting the content in a queue and allowing moderators to explicitly accept or reject content. I needed such functionality for a site I was working on so I wrote the &#8220;ActsAsModerated&#8221; plugin which allows specific columns of a model to be audited by a moderator at some later point.</p>

<p>ActsAsModerated is good for:</p>

<ul>
<li>spot-checking user generated content</li>
<li>being notified when new content is created</li>
<li>tracking changes within a record</li>
<li>spam checking</li>
</ul>


<p>Moreover, this plugin allows for custom callbacks and validations around the moderation event. This flexibility gives developers the ability to augment the moderation flow by stacking custom rules as needed. For example, a developer write code to assign a reputation score to a user and increment that score for every non-spam contribution they make. This would mean that you could auto approve any content that is made by a user above a certain score, thereby reducing the workload on moderators. I have been using this plugin for over a year on a very high-volume site and it has held up quite well, and so I thought I&#8217;d share it with the rest of the Ruby on Rails community.</p>

<h3>Download &amp; Install</h3>

<p>For those with ADD you can find acts_as_moderated here:
<a href="https://github.com/heavysixer/acts_as_moderated">https://github.com/heavysixer/acts_as_moderated</a></p>

<h3>Setup</h3>

<p>Create the moderated_records table like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="n">create_table</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="ss">:force</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="k">do</span> <span class="o">|</span><span class="n">t</span><span class="o">|</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">integer</span>  <span class="s2">&quot;recordable_id&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">string</span>   <span class="s2">&quot;recordable_type&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">integer</span>  <span class="s2">&quot;state_id&quot;</span><span class="p">,</span>             <span class="ss">:default</span> <span class="o">=&gt;</span> <span class="mi">0</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">integer</span>  <span class="s2">&quot;decision_id&quot;</span><span class="p">,</span>          <span class="ss">:default</span> <span class="o">=&gt;</span> <span class="mi">0</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">boolean</span>  <span class="s2">&quot;flagged&quot;</span><span class="p">,</span>              <span class="ss">:default</span> <span class="o">=&gt;</span> <span class="kp">false</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">integer</span>  <span class="s2">&quot;moderator_id&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">string</span>   <span class="s2">&quot;reason&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">datetime</span> <span class="s2">&quot;created_at&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">datetime</span> <span class="s2">&quot;updated_at&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">text</span>     <span class="s2">&quot;inspected_attributes&quot;</span>
</span><span class='line'>  <span class="n">t</span><span class="o">.</span><span class="n">boolean</span>  <span class="s2">&quot;rejected&quot;</span><span class="p">,</span>             <span class="ss">:default</span> <span class="o">=&gt;</span> <span class="kp">false</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">add_index</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="o">[</span><span class="s2">&quot;decision_id&quot;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;index_moderation_records_on_decision_id&quot;</span>
</span><span class='line'><span class="n">add_index</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="o">[</span><span class="s2">&quot;flagged&quot;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;index_moderation_records_on_flagged&quot;</span>
</span><span class='line'><span class="n">add_index</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="o">[</span><span class="s2">&quot;moderator_id&quot;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;index_moderation_records_on_moderator_id&quot;</span>
</span><span class='line'><span class="n">add_index</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="o">[</span><span class="s2">&quot;recordable_id&quot;</span><span class="p">,</span> <span class="s2">&quot;recordable_type&quot;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;index_moderation_records_on_recordable_id_and_recordable_type&quot;</span>
</span><span class='line'><span class="n">add_index</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="o">[</span><span class="s2">&quot;rejected&quot;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;index_moderation_records_on_rejected&quot;</span>
</span><span class='line'><span class="n">add_index</span> <span class="s2">&quot;moderation_records&quot;</span><span class="p">,</span> <span class="o">[</span><span class="s2">&quot;state_id&quot;</span><span class="o">]</span><span class="p">,</span> <span class="ss">:name</span> <span class="o">=&gt;</span> <span class="s2">&quot;index_moderation_records_on_state_id&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Usage</h3>

<p>ActsAsModerated has two integration points. The first is within the model(s) to be moderated, which can be done like so:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Comment</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">acts_as_moderated</span> <span class="ss">:body</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The second integration point is the class that acts as the moderator. Typically this is some user or account class. The idea is that behind this integration point is to create an audit trail for decisions made by the moderator if you ever need to watch the watcher.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="k">class</span> <span class="nc">Account</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>    <span class="n">acts_as_moderator</span>
</span><span class='line'>  <span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The plugin also supports an <strong>after_moderation</strong> callback on the record being moderated, which you can use to take action based on what the moderator did. For example:</p>

<ul>
<li>Delete the record if it is inappropriate or spam</li>
<li>Email the content creator that their content has been approved / denied</li>
</ul>


<p>There are several dynamically created methods added to every acts_as_moderated class which moderators can use as a shortcut for making decisions. For example where <strong>@moderator</strong> is an object with <strong>acts_as_moderator</strong> applied:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="vi">@comment</span><span class="o">.</span><span class="n">marked_spam_by_moderator</span><span class="p">(</span><span class="vi">@moderator</span><span class="p">)</span>
</span><span class='line'>  <span class="vi">@comment</span><span class="o">.</span><span class="n">marked_scam_by_moderator</span><span class="p">(</span><span class="vi">@moderator</span><span class="p">,</span> <span class="ss">:reason</span> <span class="o">=&gt;</span> <span class="s1">&#39;this is obviously a scam, please delete.&#39;</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Default Ordering, Callbacks &amp; Flagging</h3>

<p>The ModerationRecord class has a <strong>named_scope</strong> called <em>queue</em>, which will return records sorted oldest to newest. However, if you flag a record it will be returned first regardless of its age relative to unflagged records. This is useful if you want to ensure that moderators see potentially dangerous records first. A good way to flag a record is using the <strong>after_moderated</strong> callback for example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Comment</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">acts_as_moderated</span> <span class="ss">:body</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">after_moderated</span><span class="p">(</span><span class="n">moderation_record</span><span class="p">)</span>
</span><span class='line'>    <span class="n">moderation_record</span><span class="o">.</span><span class="n">flag!</span> <span class="k">if</span> <span class="n">body</span> <span class="o">=~</span> <span class="sr">/viagra/i</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>The moderation record will attempt to make callbacks on the model being moderated after a record is first created <strong>after_moderation</strong> and when a moderator rejects a record <strong>after_rejection</strong> here is an example of what they might do:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="k">class</span> <span class="nc">Story</span> <span class="o">&lt;</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span>
</span><span class='line'>  <span class="n">acts_as_moderated</span> <span class="ss">:body</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">after_moderated</span><span class="p">(</span><span class="n">moderation_record</span><span class="p">)</span>
</span><span class='line'>    <span class="n">update_attribute</span><span class="p">(</span><span class="ss">:moderated</span><span class="p">,</span> <span class="kp">true</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">def</span> <span class="nf">after_rejection</span><span class="p">(</span><span class="n">moderation_record</span><span class="p">)</span>
</span><span class='line'>    <span class="n">update_attribute</span><span class="p">(</span><span class="ss">:rejected</span><span class="p">,</span> <span class="kp">true</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Skipping moderation</h3>

<p>The moderation plugin adds an <strong>attr_accessor</strong> called <strong>skip_moderation</strong>, which when set to true will prevent a moderation
record from being created for that instance of a save. This is useful if you need to create records programmatically, which
don&#8217;t need to be moderated initially but will need to be moderated at some later point. For example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'>  <span class="vi">@story</span> <span class="o">=</span> <span class="no">ModeratedStory</span><span class="o">.</span><span class="n">create</span> <span class="c1">#creates a moderation record</span>
</span><span class='line'>  <span class="vi">@story</span> <span class="o">=</span> <span class="no">ModeratedStory</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:skip_moderation</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">)</span> <span class="c1">#does not create a moderation record</span>
</span></code></pre></td></tr></table></div></figure>


<p>A word to the wise however, since this <strong>attr_accessor</strong> prevents records from being moderated you will want to protect it from
<em>mass_assignment</em> in your model.</p>

<h4>Known Bugs</h4>

<p>Presently if you use the <strong>:always_moderate</strong> flag on a STI model it will produce a never-ending series of record updates.
I&#8217;ll keep working on this bug, in the meantime please do investigate!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[2011 Heaven - Awesome Sauce from the year that was]]></title>
    <link href="http://heavysixer.github.com/blog/2011/12/10/2011-heaven-awesome-sauce-from-the-year-that-was/"/>
    <updated>2011-12-10T18:20:00-06:00</updated>
    <id>http://heavysixer.github.com/blog/2011/12/10/2011-heaven-awesome-sauce-from-the-year-that-was</id>
    <content type="html"><![CDATA[<p>Soon the media waves will be jammed with &#8220;Best Of&#8221; lists as the last days of 2011 are ripped off the calendar. To get ahead of the curve i&#8217;ve decided to create a list of my favorite things from 2011, in no particular order.</p>

<h3>Most Helpful Coders</h3>

<p>I have a tendency to be a help vampire occasionally, it is a urge i try and suppress where possible. However, I am addicted to smart people and that often leads me down the path of ruination. The people on this list are more helpful and patient than I thought humanly possible. They were always available to answer my often hair-brained and/or panic-stricken questions. This list is not ranked in any particular order:</p>

<ul>
<li><a href="https://github.com/wayneeseguin">Wayne E. Seguin</a> - For bailing me out on RVM / SM nonsense</li>
<li><a href="https://github.com/mpapis">Michal Papis</a> - For bailing me out on RVM / SM nonsense</li>
<li><a href="https://github.com/vinnyt">Vince Toms</a> - For bailing me out on iPhone, Unix, freeBSD and just about any other technical task you can think of</li>
</ul>


<h3>Best Purchases of 2011</h3>

<ul>
<li><a href="http://www.amazon.com/gp/product/B002S51RQG/ref=oh_o02_s01_i01_details">Breville Barista Express BES860XL machine with grinder</a>
I cannot recommend this machine highly enough. I was a barista all through college and have always had a distain for <em>at home</em> expresso machines. The real beauty of this machine is that it gets enough pressure to pull a proper shot, and has a professional grade steam wand, and grinder that can be fine-tuned to boot.</li>
<li><a href="http://www.amazon.com/Where-Good-Ideas-Come-first/dp/B004MHZARA/ref=sr_1_2?ie=UTF8&amp;qid=1324082920&amp;sr=8-2">Where Good Ideas Come From</a>
I am a Steven Johnson fan-boy and his latest offering does not disappoint. It is an enthralling trip through the environments, histories and frames of mind that spark the idea of the next big thing.</li>
</ul>


<h3>Best Audio</h3>

<ul>
<li><a href="http://soundcloud.com/anoraak/night-colors-mix">Night Colors</a> Excellent music to work to</li>
<li><a href="http://www.youtube.com/watch?v=zK1mLIeXwsQ">&#8220;I Remember&#8221; - Deadmau5 &amp; Kaskade</a> This is what the Tron soundtrack should have been</li>
</ul>


<h3>Best Time Sink</h3>

<ul>
<li><a href="http://imgur.com/gallery/t7fFs">Imgur</a></li>
<li><a href="http://knowyourmeme.com/">Know Your Meme</a></li>
<li><a href="http://www.cartoonnetwork.com/tv_shows/adventuretime/index.html">Adventure Time</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[CSS Anti-patterns]]></title>
    <link href="http://heavysixer.github.com/blog/2011/12/04/css-anti-patterns/"/>
    <updated>2011-12-04T11:06:00-06:00</updated>
    <id>http://heavysixer.github.com/blog/2011/12/04/css-anti-patterns</id>
    <content type="html"><![CDATA[<p>Over the last month of two I have been working on a large enterprise Rails site. The backend has been implemented by a core group of developers but the frontend CSS and HTML have been handed off several times. As I worked to refactor some of the views I noticed several anti-patterns reoccurring in the code that I thought I would highlight and propose work arounds. While all of the examples I present in this file are extracted directly from the site in question I have seen them occur over and over again on other projects.</p>

<h2>1. Unclear Naming Conventions</h2>

<p>If a tag in an HTML page performs a task then a good CSS name should describe what the job is. It should have semantic value and should not where possible describe only visual attributes.</p>

<figure class='code'><figcaption><span>Anti-pattern Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'><span class="nc">.teal</span> <span class="p">{</span>
</span><span class='line'><span class="k">color</span><span class="o">:</span> <span class="m">#1EC5E9</span><span class="p">;</span>
</span><span class='line'><span class="k">font-style</span><span class="o">:</span> <span class="k">italic</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>This class name gives very little semantic value to tag it is applied to. The class &#8220;teal&#8221; only describes the visualness of the tag. Furthermore this name is only relevant while the visual design of the page stays the same. If the design changes then every instance of the &#8220;teal&#8221; class will need to be removed throughout the codebase if the color changes. What is worse is if the CSS attributes within the class are updated without changing the name then the name becomes meaningless. A better approach would be to understand what the teal color is for. If it is meant to draw emphasis to a bit of text then choose a name like &#8220;highlight&#8221; so that it is more clear what job it is to perform.</p>

<h2>2. Invalid Declarations</h2>

<p>When writing CSS periodically run your classes through a CSS validator to ensure its syntax is correct. The problem with invalid declarations is that they may not break the tag in question but may corrupt the rest of the cascade causing classes defined later in the file from working. Whenever I am hunting down a CSS error the first thing I do is ensure I am working off a valid document. I can&#8217;t tell you how many times just fixing the code in one part of the file fixed mystery bugs that appeared lower in the document.</p>

<h2>3. Unnecessary verboseness</h2>

<p>  Where possible try to compact your CSS attributes into one line:</p>

<figure class='code'><figcaption><span>Anti-pattern Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nt">background</span><span class="o">:</span> <span class="nf">#2175BE</span><span class="o">;</span>
</span><span class='line'>  <span class="nt">background-image</span><span class="o">:</span> <span class="nt">url</span><span class="o">(../</span><span class="nt">images</span><span class="o">/</span><span class="nt">bottomshadownav</span><span class="nc">.png</span><span class="o">);</span>
</span><span class='line'>  <span class="nt">background-position</span><span class="o">:</span> <span class="nt">bottom</span><span class="o">;</span>
</span><span class='line'>  <span class="nt">background-repeat</span><span class="o">:</span> <span class="nt">repeat-x</span><span class="o">;</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Improved Version</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nt">background</span><span class="o">:</span> <span class="nf">#2175BE</span> <span class="nt">url</span><span class="o">(../</span><span class="nt">images</span><span class="o">/</span><span class="nt">bottomshadownav</span><span class="nc">.png</span><span class="o">)</span> <span class="nt">repeat-x</span> <span class="nt">bottom</span><span class="o">;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>4. Overly Specific Classes</h2>

<p>I strive to make CSS classes do only one thing. That does not mean that my classes only have only one attribute declaration, but it means that I try to assign them only one job to perform. This allows me to build up complex behaviors and visuals to html tags by combining several simple CSS classes. Resist the urge to add properties to your class that doesn&#8217;t describe the job it does. This will also make your HTML more clear to read, and easier to extend. Consider the two examples below:</p>

<figure class='code'><figcaption><span>Anti-pattern Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.slider</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">height</span><span class="o">:</span> <span class="m">27px</span><span class="p">;</span>
</span><span class='line'>    <span class="k">float</span><span class="o">:</span> <span class="k">left</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Improved Version</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.slider</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">height</span><span class="o">:</span> <span class="m">27px</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="nc">.left</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">float</span><span class="o">:</span> <span class="k">left</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>5. Browser Specific Overrides</h2>

<p>Where possible resist the urge to place browser specific hacks in the master CSS file. The proper approach is to peel these classes off into an override stylesheet that will be loaded only when the user is using that particular browser. The reason we put override classes in their own file is for two reasons. It simplifies the master CSS file, and gives the developer an easy way to eliminate CSS from the site when the site no longer needs to support a deprecated browser.</p>

<figure class='code'><figcaption><span>Anti-pattern Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.decile</span> <span class="nt">img</span> <span class="p">{</span>
</span><span class='line'>  <span class="err">_</span><span class="k">margin</span><span class="o">:</span> <span class="m">0px</span> <span class="c">/* IE 6 Hack */</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>6. Needless Duplication</h2>

<p>Part of writing good CSS is to generalize common tasks where possible. In the example below you&#8217;ll notice that both classes are essentially the same.</p>

<figure class='code'><figcaption><span>Anti-pattern Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.comparator</span> <span class="nt">a</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">margin-right</span><span class="o">:</span> <span class="m">3px</span><span class="p">;</span>
</span><span class='line'>  <span class="k">padding</span><span class="o">:</span> <span class="m">3px</span> <span class="m">13px</span> <span class="m">3px</span> <span class="m">13px</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="nc">.ambition</span> <span class="nt">a</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">padding</span><span class="o">:</span> <span class="m">3px</span> <span class="m">13px</span> <span class="m">3px</span> <span class="m">13px</span><span class="p">;</span>
</span><span class='line'>  <span class="k">margin-right</span><span class="o">:</span> <span class="m">3px</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Improved Version</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nt">a</span><span class="nc">.link</span> <span class="p">{</span>
</span><span class='line'>    <span class="k">padding</span><span class="o">:</span> <span class="m">3px</span> <span class="m">10px</span> <span class="m">3px</span> <span class="m">10px</span><span class="p">;</span>
</span><span class='line'>    <span class="k">margin-right</span><span class="o">:</span> <span class="m">3px</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>7. Overuse of exclamation point</h2>

<p>The &#8220;!&#8221; override is a brute force method to ensure an attribute of your class cannot be overwritten. This should be used as a last resort and not to mask poor design or abstraction of classes. Overuse of the exclamation point is like a shouting match between all your CSS classes, almost never ends well.</p>

<h2>8. &#8220;Cargo Culting&#8221; through Copy + Paste</h2>

<p>Copying CSS en masse and pasting it into the document without making fundamental changes to the class can be a sign of disconnect between the designer and developer or a signal that the developer / designer doesn&#8217;t know (or care) about how the copied CSS works. Bulk copying CSS creates deadweight in the CSS file and makes it harder to maintain and extend.</p>

<p>In the first case where a developer is implementing a design given to them by a front-end developer it is entirely possible the developer won&#8217;t know how the CSS works. Later, they may find themselves needing to replicate a style elsewhere in the site. Often this means they bulk copy several classes and paste them elsewhere in the document. Typically, they make a trivial changes needed e.g. change the font-size and then rename the class. The proper approach would be to abstract the first class so that it is more generalized and can service both instances of how it needs to be implemented.</p>

<p>However, I found several examples where entire blocks of code appeared three and four times in the same file with absolutely no difference! This is absolutely unacceptable in a professional product.</p>

<h2>9. Unused Classes</h2>

<p>With any site under constant development it is easy for classes to become unused within the html. Developers and designers must make it part of their development process to remove unused classes from the CSS otherwise the site can become bogged down with all the deadweight inside the CSS file. There are projects like &#8220;deadweight&#8221; which are specifically dedicated to helping you prune your CSS of unused code.</p>

<h2>10. Needless Namespacing</h2>

<p>Namespacing is used to change the way a child class works when its parent class changes. This is a great way to keep your HTML and CSS flexible because it means that a single change to the parent element can change the look and feel of all the containing children. However, if you over namespace your CSS by binding it to specific html tags where not absolutely needed you make the CSS brittle and hard to maintain.</p>

<figure class='code'><figcaption><span>Anti-pattern Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.qipp-inputs</span> <span class="nt">table</span> <span class="nt">tr</span><span class="nc">.metric</span> <span class="nt">td</span><span class="nc">.metric_name</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">border-bottom</span><span class="o">:</span> <span class="m">1px</span> <span class="k">dotted</span> <span class="m">#B6CBD2</span><span class="p">;</span>
</span><span class='line'>  <span class="k">padding-left</span><span class="o">:</span> <span class="m">20px</span><span class="p">;</span>
</span><span class='line'>  <span class="k">text-align</span><span class="o">:</span> <span class="k">left</span> <span class="cp">!important</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>




<figure class='code'><figcaption><span>Improved Example</span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='css'><span class='line'>  <span class="nc">.qipp-inputs</span> <span class="nc">.metric</span> <span class="nt">td</span><span class="nc">.metric_name</span> <span class="p">{</span>
</span><span class='line'>  <span class="k">border-bottom</span><span class="o">:</span> <span class="m">1px</span> <span class="k">dotted</span> <span class="m">#B6CBD2</span><span class="p">;</span>
</span><span class='line'>  <span class="k">padding-left</span><span class="o">:</span> <span class="m">20px</span><span class="p">;</span>
</span><span class='line'>  <span class="k">text-align</span><span class="o">:</span> <span class="k">left</span> <span class="cp">!important</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I welcome any discussion or feedback on these patterns and would love to improve this document where possible. What anti-patterns have you seen in CSS files you&#8217;ve worked on?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Transactions In Rails]]></title>
    <link href="http://heavysixer.github.com/blog/2011/12/01/transactions-in-rails/"/>
    <updated>2011-12-01T11:39:00-06:00</updated>
    <id>http://heavysixer.github.com/blog/2011/12/01/transactions-in-rails</id>
    <content type="html"><![CDATA[<p>Recently I was tasked to write tests for the transactions of an existing application. This gave me the opportunity to learn more about the codebase, while also improving the test coverage. Generally, most of the transaction code looked fine. However, there were some instances where transactions were used incorrectly or inefficiently. I assumed this is just because of a misunderstanding of how transactions work within Rails, and so I thought iʼd take some time and give an overview of the common errors I found and some best practices for using transactions in Rails.</p>

<p>Let me also state at the beginning that most of these examples are not my own, they come directly from the Rails source, which give example usages of applying transactions RTFM FTW.</p>

<p><a href="http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html">http://api.rubyonrails.org/classes/ActiveRecord/Transactions/ClassMethods.html</a></p>

<h3>Reasons for transactions</h3>

<p>We use transactions as a protective wrapper around SQL statements to ensure changes to the database only occur when all actions succeed together. Transaction help the developer enforce data integrity within the application. The canonical example of transactions is the banking method where funds are withdrawn from one account and deposited into the next. If either of these steps fail, then the entire process should be reset. This example can be described in code this way:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">david</span><span class="o">.</span><span class="n">withdrawal</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'>  <span class="n">mary</span><span class="o">.</span><span class="n">deposit</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>In Rails transactions are available as class and instance methods for all ActiveRecord models. This means either of these approaches are equally valid:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Client</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@client</span><span class="o">.</span><span class="n">users</span><span class="o">.</span><span class="n">create!</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">clients</span><span class="p">(</span><span class="kp">true</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">destroy!</span>
</span><span class='line'>  <span class="no">Product</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">destroy!</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="vi">@client</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="vi">@client</span><span class="o">.</span><span class="n">users</span><span class="o">.</span><span class="n">create!</span>
</span><span class='line'>  <span class="vi">@user</span><span class="o">.</span><span class="n">clients</span><span class="p">(</span><span class="kp">true</span><span class="p">)</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">destroy!</span>
</span><span class='line'>  <span class="no">Product</span><span class="o">.</span><span class="n">first</span><span class="o">.</span><span class="n">destroy!</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>You may also notice that there are several different model classes referenced in these transactions. It is perfectly fine to mix model types inside a single transaction block. This is because the transaction is bound to the database connection not the model instance.
As a rule, transactions are only needed when changes to multiple records must succeed as a single unit. Additionally, Rails already wraps the #save and #destroy methods in a transaction, therefore a transaction is never needed when updating a single record.</p>

<h3>Transaction Rollback Triggers</h3>

<p>Transactions reset the state of records through a process called a rollback. In Rails, rollbacks are only triggered by an exception. This is a crucial point to understand; I saw several transaction blocks that would never rollback because the containing code could not throw an exception. Here I have slightly modified our banking example from before:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">david</span><span class="o">.</span><span class="n">update_attribute</span><span class="p">(</span><span class="ss">:amount</span><span class="p">,</span> <span class="n">david</span><span class="o">.</span><span class="n">amount</span> <span class="o">-</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'>  <span class="n">mary</span><span class="o">.</span><span class="n">update_attribute</span><span class="p">(</span><span class="ss">:amount</span><span class="p">,</span> <span class="mi">100</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>In Rails <em>#update_attribute</em> is designed not to throw an exception when an update fails. It returns false, and for this reason you should ensure that the methods used throw an exception upon failure. A better way to write the previous example would be:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">david</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:amount</span> <span class="o">=&gt;</span> <span class="o">-</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'>  <span class="n">mary</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:amount</span> <span class="o">=&gt;</span> <span class="mi">100</span><span class="p">)</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Note: The bang modifier (!) is a rails convention for a method which will throw an exception upon failure.</p>

<p>I also saw examples in the code where records were found inside of transactions using magic finders <em>#find_by</em><some attribute><em>. By design magic finders will return nil when no record is returned. This is in contrast to the normal </em>#find_ method which throws an <strong>ActiveRecord::RecordNotFound</strong> exception. Consider this example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">david</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">find_by_name</span><span class="p">(</span><span class="s2">&quot;david&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">david</span><span class="o">.</span><span class="n">id</span> <span class="o">!=</span> <span class="n">john</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
</span><span class='line'>    <span class="n">john</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:amount</span> <span class="o">=&gt;</span> <span class="o">-</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'>    <span class="n">mary</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:amount</span> <span class="o">=&gt;</span> <span class="mi">100</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>Do you see the logic error? The nil object will have an id attribute and it will mask the fact that the desired record was not returned. While this doesn’t cause an error in the transaction it will still lead to a loss of data integrity, because the application is updating where it shouldn’t. Remember a transaction defines a block of code which must succeed as an atomic unit. This means we should raise an exception when a logical dependency like this is not met. Here is how the code should be written:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Base</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="n">david</span> <span class="o">=</span> <span class="no">User</span><span class="o">.</span><span class="n">find_by_name</span><span class="p">(</span><span class="s2">&quot;david&quot;</span><span class="p">)</span>
</span><span class='line'>  <span class="k">raise</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">RecordNotFound</span> <span class="k">if</span> <span class="n">david</span><span class="o">.</span><span class="n">nil?</span>
</span><span class='line'>  <span class="k">if</span><span class="p">(</span><span class="n">david</span><span class="o">.</span><span class="n">id</span> <span class="o">!=</span> <span class="n">john</span><span class="o">.</span><span class="n">id</span><span class="p">)</span>
</span><span class='line'>    <span class="n">john</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:amount</span> <span class="o">=&gt;</span> <span class="o">-</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'>    <span class="n">mary</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:amount</span> <span class="o">=&gt;</span> <span class="mi">100</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>When the exception occurs it will be raised outside of the transaction block after the rollback has completed. Your application code must be ready to catch this exception as it bubbles up through the application stack.</p>

<p>It is also possible to invalidate a transaction without raising an exception that will propagate upwards by using <strong>ActiveRecord::Rollback</strong>. This special exception allows you to invalidate a transaction and reset the database records without needing to rescue elsewhere in your code.</p>

<h3>When To Use Nested Transactions</h3>

<p>One of the common mistakes I saw in the codebase is the misuse or overuse of nested transactions. When you nest a transaction inside another transaction this has the effect of making the child transaction a part of the parent. This can have surprising results, take this example from the Rails API documentation:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">User</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="no">User</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="s1">&#39;Kotori&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="no">User</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>    <span class="no">User</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="s1">&#39;Nemu&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">raise</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Rollback</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>As mentioned previously <strong>ActiveRecord::Rollback</strong> does not propagate outside of the containing transaction block and so the parent transaction does not receive the exception nested inside the child. Since the contents of the child transaction are lumped into the parent transaction both records are created! I find it easier to think of nested transactions like the child who dumps its contents into the parent container, leaving the child transaction empty.</p>

<p>To ensure a rollback is received by the parent transaction you must add the <em>:requires_new => true</em>. option to the child transaction. Again using the example from Rails source you would trigger a parent’s Rollback like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">User</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="no">User</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="s1">&#39;Kotori&#39;</span><span class="p">)</span>
</span><span class='line'>  <span class="no">User</span><span class="o">.</span><span class="n">transaction</span><span class="p">(</span><span class="ss">:requires_new</span> <span class="o">=&gt;</span> <span class="kp">true</span><span class="p">)</span> <span class="k">do</span>
</span><span class='line'>    <span class="no">User</span><span class="o">.</span><span class="n">create</span><span class="p">(</span><span class="ss">:username</span> <span class="o">=&gt;</span> <span class="s1">&#39;Nemu&#39;</span><span class="p">)</span>
</span><span class='line'>    <span class="k">raise</span> <span class="no">ActiveRecord</span><span class="o">::</span><span class="no">Rollback</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<p>A transaction only acts upon the current database connection. If your application writes to multiple databases at once you will need to wrap the method inside a nested transaction. For example:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='ruby'><span class='line'><span class="no">Client</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>  <span class="no">Product</span><span class="o">.</span><span class="n">transaction</span> <span class="k">do</span>
</span><span class='line'>    <span class="n">product</span><span class="o">.</span><span class="n">buy</span><span class="p">(</span><span class="vi">@quantity</span><span class="p">)</span>
</span><span class='line'>    <span class="n">client</span><span class="o">.</span><span class="n">update_attributes!</span><span class="p">(</span><span class="ss">:sales_count</span> <span class="o">=&gt;</span> <span class="vi">@sales_count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span>
</span><span class='line'>  <span class="k">end</span>
</span><span class='line'><span class="k">end</span>
</span></code></pre></td></tr></table></div></figure>


<h3>Callback around Transactions</h3>

<p>As mentioned previously <em>#save</em> and <em>#destroy</em> are wrapped inside a transaction. This means that callbacks like <em>#after_save</em> is still part of the active transaction which might still be rolled back! Therefore if you want code to execute that is guaranteed to execute outside of the transaction use one of the transaction specific callbacks like <em>#after_commit</em> or <em>#after_rollback</em>.</p>

<h3>Transaction Gotchas</h3>

<p>Do not catch an <strong>ActiveRecord::RecordInvalid</strong> exception inside a transaction because the this exception invalidates the transaction on some databases like Postgres. Once the transaction has been invalidated you must restart it from the beginning for it to work correctly.</p>

<p>When testing rollbacks or transaction related callbacks that happen after rollback you will want to turn off transactional_fixtures which are on by default in most test frameworks.</p>

<h3>Common Anti-patterns To Avoid</h3>

<ol>
<li>Using a transaction when only a single record is updated</li>
<li>Needlessly nesting transactions</li>
<li>Transactions that contain code, which won’t cause a rollback</li>
<li>Use of transactions in a controller</li>
</ol>

]]></content>
  </entry>
  
</feed>

