<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
  <channel>
    <title>Steven Soroka - !!blog? : </title>
    <link>http://blog.stevensoroka.ca/articles.rss</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>Now without wood shavings</description>
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/StevenSorokasBlog" /><feedburner:info uri="stevensorokasblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>how to write tests for observers</title>
      <description>&lt;p&gt;Rails Observers are especially important to test.&amp;nbsp; With validation errors, they'll either silently fail without you knowing, or they'll raise exceptions and break your production code.&lt;/p&gt;
&lt;p&gt;You'll want to disable your observers in your config/environments/test.rb environment, because they complicate unit tests:&lt;/p&gt;
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;  config.active_record.observers = []&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Here's what my observer tests look like:&lt;/p&gt;
&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;require &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;spec_helper&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;

describe &lt;span class="co"&gt;ArchiveObserver&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
  before(&lt;span class="sy"&gt;:each&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt;
    entry = &lt;span class="co"&gt;Factory&lt;/span&gt;.create(&lt;span class="sy"&gt;:entry&lt;/span&gt;, &lt;span class="sy"&gt;:orbits&lt;/span&gt; =&amp;gt; [&lt;span class="co"&gt;Factory&lt;/span&gt;.create(&lt;span class="sy"&gt;:orbit&lt;/span&gt;), &lt;span class="co"&gt;Factory&lt;/span&gt;.create(&lt;span class="sy"&gt;:orbit&lt;/span&gt;)])
    &lt;span class="iv"&gt;@archive&lt;/span&gt; = &lt;span class="co"&gt;Factory&lt;/span&gt;.create(&lt;span class="sy"&gt;:archive&lt;/span&gt;, &lt;span class="sy"&gt;:entry&lt;/span&gt; =&amp;gt; entry)
  &lt;span class="r"&gt;end&lt;/span&gt;
  
  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;after_create&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
    it &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;creates 1 new_archive_event per orbit&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
      lambda {
        &lt;span class="co"&gt;ArchiveObserver&lt;/span&gt;.instance.after_create(&lt;span class="iv"&gt;@archive&lt;/span&gt;)
      }.should change(&lt;span class="co"&gt;NotificationEvents&lt;/span&gt;::&lt;span class="co"&gt;NewArchiveEvent&lt;/span&gt;, &lt;span class="sy"&gt;:count&lt;/span&gt;).by(&lt;span class="i"&gt;2&lt;/span&gt;)
    &lt;span class="r"&gt;end&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
  
  describe &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;after_destroy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
    before(&lt;span class="sy"&gt;:each&lt;/span&gt;) &lt;span class="r"&gt;do&lt;/span&gt;
      &lt;span class="co"&gt;ArchiveObserver&lt;/span&gt;.instance.after_create(&lt;span class="iv"&gt;@archive&lt;/span&gt;)
    &lt;span class="r"&gt;end&lt;/span&gt;

    it &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;destroys any new_archive_events it created&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt; &lt;span class="r"&gt;do&lt;/span&gt;
      lambda {
        &lt;span class="co"&gt;ArchiveObserver&lt;/span&gt;.instance.after_destroy(&lt;span class="iv"&gt;@archive&lt;/span&gt;)
      }.should change(&lt;span class="co"&gt;NotificationEvents&lt;/span&gt;::&lt;span class="co"&gt;NewArchiveEvent&lt;/span&gt;, &lt;span class="sy"&gt;:count&lt;/span&gt;).by(&lt;span class="i"&gt;-2&lt;/span&gt;)
    &lt;span class="r"&gt;end&lt;/span&gt;
  &lt;span class="r"&gt;end&lt;/span&gt;
&lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;

</description>
      <pubDate>Fri, 11 Jun 2010 15:43:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:dfcb6729-b2e6-4ff3-bbaa-d88314e57f71</guid>
      <comments>http://blog.stevensoroka.ca/2010/06/11/how-to-write-tests-for-observers#comments</comments>
      <category>Rails</category>
      <category>rails</category>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/I2DNN3SEW14/how-to-write-tests-for-observers</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2010/06/11/how-to-write-tests-for-observers</feedburner:origLink></item>
    <item>
      <title>Faster Ruby Gem installs</title>
      <description>&lt;p&gt;Ruby gems install slowly because rdoc and ri documentation are generated as the gems install.&amp;nbsp; Since this is rarely used, why not turn it off?&amp;nbsp; I always check the internet for up-to-date docs anyway, which give me a chance to see if there's a newer version of the gem out.&lt;/p&gt;
&lt;p&gt;To turn these off, modify your ~/.gemrc file and add the line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;br /&gt;    gem: --no-rdoc --no-ri&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;

</description>
      <pubDate>Tue, 06 Apr 2010 11:13:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:ac59e4f3-c557-4f0c-938b-a1550dc0eef4</guid>
      <comments>http://blog.stevensoroka.ca/2010/04/06/faster-ruby-gem-installs#comments</comments>
      <category>Ruby</category>
      <category>ruby</category>
      <category>gems</category>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/5utQ-ipvuFk/faster-ruby-gem-installs</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2010/04/06/faster-ruby-gem-installs</feedburner:origLink></item>
    <item>
      <title>ActiveRecord-driven global configuration plugin for Rails</title>
      <description>&lt;p&gt;I just released a simple plugin called &lt;a href="http://github.com/ssoroka/global_config"&gt;global_config&lt;/a&gt; for keeping track of application configuration settings in your database.&lt;/p&gt;

&lt;p&gt;&lt;img width="170" height="113" alt="" src="/files/Image/86196587.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;The nice thing about it is that it uses method missing on a GlobalConfig class to dynamically grab and set settings. &amp;nbsp;For example, if you had two settings called admin_email and memcached_server_ip, you could fetch them like so:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;    &lt;span class="co"&gt;GlobalConfig&lt;/span&gt;.admin_email &lt;span class="c"&gt;# =&amp;gt; 'admin@example.com'&lt;/span&gt;
    &lt;span class="co"&gt;GlobalConfig&lt;/span&gt;.memcached_server_ip &lt;span class="c"&gt;# =&amp;gt; '127.0.0.15'&lt;/span&gt;&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;You can also set the values in migrations (or anywhere) like so:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;    &lt;span class="co"&gt;GlobalConfig&lt;/span&gt;.admin_email = &lt;span class="s"&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="k"&gt;webadmin@example.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The next thing I'd implement is an admin page for managing the configuration settings.  If there's some interest in it, I may add this to the plugin (lemme know).&lt;/p&gt;

&lt;p&gt;Caching support is built in; Memcached is recommended.&lt;/p&gt;


</description>
      <pubDate>Mon, 22 Mar 2010 15:52:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:a51529d5-9205-4ad4-993c-4b4b9d14e119</guid>
      <comments>http://blog.stevensoroka.ca/2010/03/22/activerecord-driven-global-configuration-plugin-for-rails#comments</comments>
      <category>Rails</category>
      <category>rails</category>
      <category>plugin</category>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/vCaKMvv_pfI/activerecord-driven-global-configuration-plugin-for-rails</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2010/03/22/activerecord-driven-global-configuration-plugin-for-rails</feedburner:origLink></item>
    <item>
      <title>Methods are objects</title>
      <description>You may know that everything in Ruby is an object, but did you know that methods are objects?

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;notextile&gt;&lt;span class="CodeRay"&gt;  my_string = &lt;span class="s"&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;span class="k"&gt;test&lt;/span&gt;&lt;span class="dl"&gt;&amp;quot;&lt;/span&gt;&lt;/span&gt;
  size_method = my_string.method(&lt;span class="sy"&gt;:size&lt;/span&gt;)
  size_method.arity   &lt;span class="c"&gt;# 0&lt;/span&gt;
  size_method.call  &lt;span class="c"&gt;# 4&lt;/span&gt;&lt;/span&gt;&lt;/notextile&gt;&lt;/pre&gt;&lt;/div&gt;

You can request a method's arity (basically the number of parameters it takes), call it, or even convert it to a proc and pass it to another method.  Interesting, n'est pas?

</description>
      <pubDate>Tue, 02 Mar 2010 23:38:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:3947caf5-a8ef-4a39-934c-f220e9a03cf1</guid>
      <comments>http://blog.stevensoroka.ca/2010/03/02/methods-are-objects#comments</comments>
      <category>Ruby</category>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/ObuLCEqB-BY/methods-are-objects</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2010/03/02/methods-are-objects</feedburner:origLink></item>
    <item>
      <title>how could conditionals be evil?</title>
      <description>&lt;p&gt;If you've seen the &lt;a href="http://www.antiifcampaign.com/"&gt;Anti-If Campaign&lt;/a&gt;, and overheard talk about the "if" statement being evil, you might be thinking "Why? It's a core part of any language, and you couldn't write a program without them", and you'd be right.&lt;/p&gt;

&lt;p&gt;The conditional is not evil itself, it smells of evil.  The conditional invites evil not because of what it does, but because of what it shouldn't be doing.  It's an indication of a code smell, and should be a metric that you track.  If you don't track it, you need to at least know what to watch for.&lt;/p&gt;

&lt;p&gt;For example: I was working on my code today, and I found a constant that violated the &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;Single Responsibility Principle&lt;/a&gt;.  It managed both A) the various pages in a checkout process, and B) which "next" and "previous" buttons displayed on each page.&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;  &lt;span class="co"&gt;STATES&lt;/span&gt; = {
      &lt;span class="sy"&gt;:details&lt;/span&gt; =&amp;gt; [&lt;span class="pc"&gt;nil&lt;/span&gt;, &lt;span class="sy"&gt;:payment&lt;/span&gt;],
      &lt;span class="sy"&gt;:payment&lt;/span&gt; =&amp;gt; [&lt;span class="sy"&gt;:details&lt;/span&gt;, &lt;span class="sy"&gt;:final_review&lt;/span&gt;],
      &lt;span class="sy"&gt;:final_review&lt;/span&gt; =&amp;gt; [&lt;span class="sy"&gt;:payment&lt;/span&gt;, &lt;span class="sy"&gt;:confirmation&lt;/span&gt;],
      &lt;span class="sy"&gt;:confirmation&lt;/span&gt; =&amp;gt; [&lt;span class="pc"&gt;nil&lt;/span&gt;, &lt;span class="pc"&gt;nil&lt;/span&gt;]
  }&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The subtle problem here is that the confirmation page doesn't have a back button, but the application can easily send the user back a page if the payment processing fails for some legitimate reason (Maybe the payment gateway is down?).  This seemingly innocuous violation of &lt;a href="http://en.wikipedia.org/wiki/Single_responsibility_principle"&gt;SRP&lt;/a&gt; caused an explosion of IF statements throughout the application.  One of the best examples of this is:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;      &lt;span class="r"&gt;if&lt;/span&gt; !&lt;span class="iv"&gt;@checkout&lt;/span&gt;.valid?
        &lt;span class="r"&gt;if&lt;/span&gt; &lt;span class="iv"&gt;@checkout&lt;/span&gt;.state.previous.present?
          &lt;span class="iv"&gt;@checkout&lt;/span&gt;.state.previous!
        &lt;span class="r"&gt;elsif&lt;/span&gt; &lt;span class="iv"&gt;@checkout&lt;/span&gt;.state.is_confirmation?
          &lt;span class="iv"&gt;@checkout&lt;/span&gt;.state.set_state(&lt;span class="sy"&gt;:final_review&lt;/span&gt;)
        &lt;span class="r"&gt;end&lt;/span&gt;
      &lt;span class="r"&gt;end&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Three conditionals just to move back a page when there are errors.  Once I removed the violation, the code nicely cleaned up to a single line with one reasonable conditional:&lt;/p&gt;

&lt;div class="CodeRay"&gt;&lt;pre&gt;&lt;span class="CodeRay"&gt;      &lt;span class="iv"&gt;@checkout&lt;/span&gt;.state.previous! &lt;span class="r"&gt;if&lt;/span&gt; !&lt;span class="iv"&gt;@checkout&lt;/span&gt;.valid?&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Conditionals themselves are not evil, they're needed to get the job done.  Take a good look at your code, though; if you see a lot of "if", "case", ternary, or other conditionals, you likely have a problem somewhere.  Move the conditional in to the class that's responsible for it, avoid case statements that do something different depending on some enumerator value or state.&lt;/p&gt;

&lt;p&gt;Conditionals smell a little.  In numbers, they outright stink!&lt;/p&gt;</description>
      <pubDate>Tue, 24 Nov 2009 11:06:00 -0600</pubDate>
      <guid isPermaLink="false">urn:uuid:07de9d65-32fb-4721-a926-1ed4e6fed628</guid>
      <comments>http://blog.stevensoroka.ca/2009/11/24/how-could-conditionals-be-evil#comments</comments>
      <category>Ruby</category>
      <category>conditionals</category>
      <category>evil</category>
      <category>case</category>
      <category>switch</category>
      <category>ruby</category>
      <trackback:ping>http://blog.stevensoroka.ca/trackbacks?article_id=93</trackback:ping>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/hk1eCzq0HIc/how-could-conditionals-be-evil</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2009/11/24/how-could-conditionals-be-evil</feedburner:origLink></item>
    <item>
      <title>Running migration code in the console</title>
      <description>&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/__uXlNQ4RII&amp;hl=en&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/__uXlNQ4RII&amp;hl=en&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

&lt;p&gt;This is a useful debugging/testing/fixing tool, but not a best practice for developing apps.  So be careful with it. :-)&lt;/p&gt;

</description>
      <pubDate>Wed, 28 Oct 2009 11:15:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:06ed536c-232f-454f-946e-d51ce9dfbe37</guid>
      <comments>http://blog.stevensoroka.ca/2009/10/28/running-migration-code-in-the-console#comments</comments>
      <category>Rails</category>
      <category>rails</category>
      <category>console</category>
      <trackback:ping>http://blog.stevensoroka.ca/trackbacks?article_id=92</trackback:ping>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/coNC_Ll9ia0/running-migration-code-in-the-console</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2009/10/28/running-migration-code-in-the-console</feedburner:origLink></item>
    <item>
      <title>git pull --rebase</title>
      <description>&lt;p&gt;rather than using git pull, which merges remote changes in to your local branch, learn when to use git pull &amp;#8211;rebase to keep your history and logs clean; but only if you haven&amp;#8217;t pushed the commits anywhere yet!&lt;/p&gt;

&lt;p&gt;&lt;object width="480" height="295"&gt;
&lt;param name="movie" value="http://www.youtube.com/v/o95zRvigiMU&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" /&gt;
&lt;param name="allowFullScreen" value="true" /&gt;
&lt;param name="allowscriptaccess" value="always" /&gt;&lt;embed src="http://www.youtube.com/v/o95zRvigiMU&amp;amp;hl=en&amp;amp;fs=1&amp;amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 22 Sep 2009 19:54:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:2d128200-254a-49bf-8c0b-3d0b64288909</guid>
      <comments>http://blog.stevensoroka.ca/2009/09/22/git-pull-rebase#comments</comments>
      <category>Rails</category>
      <category>Ruby</category>
      <category>git</category>
      <category>rebase</category>
      <trackback:ping>http://blog.stevensoroka.ca/trackbacks?article_id=91</trackback:ping>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/zxtoEzwNiG8/git-pull-rebase</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2009/09/22/git-pull-rebase</feedburner:origLink></item>
    <item>
      <title>git bisect</title>
      <description>&lt;p&gt;Ok, this is my first screencast, I think I may move to video blog format&amp;#8230; &amp;nbsp;Feedback welcome.&lt;/p&gt;
&lt;p&gt;&lt;object width="480" height="295"&gt;
&lt;param name="movie" value="http://www.youtube.com/v/C1eeLdQHvGs&amp;hl=en&amp;fs=1&amp;rel=0"&gt;&lt;/param&gt;
&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;
&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;
&lt;embed src="http://www.youtube.com/v/C1eeLdQHvGs&amp;hl=en&amp;fs=1&amp;rel=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="295"&gt;&lt;/embed&gt;
&lt;/object&gt;
&lt;/p&gt;

&lt;p&gt;I know it&amp;#8217;s hard to read, you may want to make it full screen.  I&amp;#8217;ll do better on the next one. :)&lt;/p&gt;</description>
      <pubDate>Wed, 16 Sep 2009 22:54:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:64247691-f884-49e0-92cf-b24d8f056cdd</guid>
      <comments>http://blog.stevensoroka.ca/2009/09/16/git-bisect#comments</comments>
      <category>Rails</category>
      <category>Ruby</category>
      <category>git</category>
      <category>bisect</category>
      <trackback:ping>http://blog.stevensoroka.ca/trackbacks?article_id=90</trackback:ping>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/6S95n0-Tm4c/git-bisect</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2009/09/16/git-bisect</feedburner:origLink></item>
    <item>
      <title>paranoia and split personalities, for your models!</title>
      <description>&lt;p&gt;&amp;nbsp;&lt;span class="Apple-style-span" style="font-family: Times; font-size: medium; "&gt;&lt;span class="Apple-style-span" style="font-family: Arial, Verdana, sans-serif; font-size: 12px; "&gt;&amp;nbsp;&lt;a href="http://github.com/semanticart/is_paranoid/tree/master"&gt;is_paranoid&lt;/a&gt;&amp;nbsp;is exactly what I&amp;#8217;ve been looking for. &amp;nbsp;It&amp;#8217;s like acts_as_paranoid, but up to date with ActiveRecord&amp;#8217;s new default scopes, which simplifies the gem quite a bit.&lt;/span&gt; &lt;/span&gt;&lt;/p&gt;

&lt;div style="background-color: rgb(255, 255, 255); padding-top: 5px; padding-right: 5px; padding-bottom: 5px; padding-left: 5px; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font-family: Arial, Verdana, sans-serif; font-size: 12px; "&gt;
&lt;p&gt;One idea I&amp;nbsp;&lt;em&gt;really&lt;/em&gt;&amp;nbsp;like was brought on by seeing this example:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="margin-top: 1em !important; margin-right: 0px !important; margin-bottom: 1em !important; margin-left: 0px !important; padding-top: 0.5em !important; padding-right: 0.5em !important; padding-bottom: 0.5em !important; padding-left: 0.5em !important; font: normal normal normal 115%/normal Monaco, 'Courier New', monospace; line-height: 1.5em !important; font-size: 12px; background-color: rgb(248, 248, 255) !important; border-top-width: 1px !important; border-right-width: 1px !important; border-bottom-width: 1px !important; border-left-width: 1px !important; border-top-style: solid !important; border-right-style: solid !important; border-bottom-style: solid !important; border-left-style: solid !important; border-top-color: rgb(222, 222, 222) !important; border-right-color: rgb(222, 222, 222) !important; border-bottom-color: rgb(222, 222, 222) !important; border-left-color: rgb(222, 222, 222) !important; color: rgb(68, 68, 68) !important; overflow-x: auto !important; overflow-y: auto !important; "&gt;
  class Pirate &amp;lt; ActiveRecord::Base
    is_paranoid :field =&amp;gt; [:alive, false, true]
  end

  class DeadPirate &amp;lt; ActiveRecord::Base
    set_table_name :pirates
    is_paranoid :field =&amp;gt; [:alive, true, false]
  end&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Here we have the same table acting like two models based on a default scope. &amp;nbsp;So simple, yet brilliant. &amp;nbsp;Why didn&amp;#8217;t I think of this earlier?&lt;/p&gt;
&lt;p&gt;Consider this:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre style="margin-top: 1em !important; margin-right: 0px !important; margin-bottom: 1em !important; margin-left: 0px !important; padding-top: 0.5em !important; padding-right: 0.5em !important; padding-bottom: 0.5em !important; padding-left: 0.5em !important; font: normal normal normal 115%/normal Monaco, 'Courier New', monospace; line-height: 1.5em !important; font-size: 12px; background-color: rgb(248, 248, 255) !important; border-top-width: 1px !important; border-right-width: 1px !important; border-bottom-width: 1px !important; border-left-width: 1px !important; border-top-style: solid !important; border-right-style: solid !important; border-bottom-style: solid !important; border-left-style: solid !important; border-top-color: rgb(222, 222, 222) !important; border-right-color: rgb(222, 222, 222) !important; border-bottom-color: rgb(222, 222, 222) !important; border-left-color: rgb(222, 222, 222) !important; color: rgb(68, 68, 68) !important; overflow-x: auto !important; overflow-y: auto !important; "&gt;
  class User &amp;lt; ActiveRecord::Base
    is_paranoid
  end

  class UserArchive &amp;lt; ActiveRecord::Base
    set_table_name :users
  end&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;You could use the User model for every day use, and if you need to specifically look at inactive users, you use UserArchive. &amp;nbsp;Spectacularly to the point. &amp;nbsp;Of course this has uses outside the scope of is_paranoid.&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <pubDate>Wed, 15 Jul 2009 12:18:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:b34e93be-14e6-4acd-a0ae-7b2eff102b02</guid>
      <comments>http://blog.stevensoroka.ca/2009/07/15/paranoia_and_split_personalities#comments</comments>
      <category>Rails</category>
      <trackback:ping>http://blog.stevensoroka.ca/trackbacks?article_id=89</trackback:ping>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/UsVwYRwVmCY/paranoia_and_split_personalities</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2009/07/15/paranoia_and_split_personalities</feedburner:origLink></item>
    <item>
      <title>CabooseConf is a failure</title>
      <description>&lt;p&gt;If the purpose of CabooseConf is to get experienced Ruby developers together to hack out great things together, it&amp;#8217;s a failure.&lt;/p&gt;

&lt;p&gt;While about half of the tables at CabooseConf have developers at them at this second, the majority of them are chatting and browsing the web.  The anti-conf could use some leadership and direction; even a list of projects people are working on and who to contact.&lt;/p&gt;

&lt;p&gt;As it stands the open-source community is getting more benefit from random people coding while ignoring the sessions they&amp;#8217;re sitting in. &lt;/p&gt;

&lt;p&gt;Lame.&lt;/p&gt;</description>
      <pubDate>Wed, 06 May 2009 10:53:00 -0500</pubDate>
      <guid isPermaLink="false">urn:uuid:cd777b10-ea92-4e18-9ef1-6e8383ed264f</guid>
      <comments>http://blog.stevensoroka.ca/2009/05/06/cabooseconf-is-a-failure#comments</comments>
      <category>Rails</category>
      <category>Ruby</category>
      <category>railsconf</category>
      <category>cabooseconf</category>
      <trackback:ping>http://blog.stevensoroka.ca/trackbacks?article_id=76</trackback:ping>
      <link>http://feedproxy.google.com/~r/StevenSorokasBlog/~3/So6w21t3hO0/cabooseconf-is-a-failure</link>
    <feedburner:origLink>http://blog.stevensoroka.ca/2009/05/06/cabooseconf-is-a-failure</feedburner:origLink></item>
  </channel>
</rss>

