<?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:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>metautonomo.us</title>
	
	<link>http://metautonomo.us</link>
	<description>&lt;strong&gt;meta-&lt;/strong&gt; &gt; &lt;em&gt;one level of description up&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;autonomy&lt;/strong&gt; &gt; &lt;em&gt;independence; self-direction&lt;/em&gt;&lt;br /&gt;&lt;strong&gt;metautonomous&lt;/strong&gt; &gt; &lt;em&gt;autonomous through code&lt;/em&gt;</description>
	<lastBuildDate>Mon, 30 Aug 2010 23:01:33 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/metautonomous" /><feedburner:info uri="metautonomous" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Rails 3.0 release!</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/394C9pwhEN4/</link>
		<comments>http://metautonomo.us/2010/08/30/rails-3-0-release/#comments</comments>
		<pubDate>Mon, 30 Aug 2010 23:01:33 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[meta_search]]></category>
		<category><![CDATA[meta_where]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=509</guid>
		<description><![CDATA[So, the Rails team released Rails 3.0 yesterday, on my birthday. I am claiming it as my birthday present. Anyway, I ran a quick test on MetaWhere and MetaSearch and everything is still passing, so we should be good to go! Let me know if it&#8217;s not the case.]]></description>
			<content:encoded><![CDATA[<p>So, the Rails team <a href="http://weblog.rubyonrails.org/2010/8/29/rails-3-0-it-s-done">released Rails 3.0</a> yesterday, on my birthday. I am claiming it as my birthday present. Anyway, I ran a quick test on MetaWhere and MetaSearch and everything is still passing, so we should be good to go! Let me know if it&#8217;s not the case.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/PWbGWtpMKoFw3-GFDGp0lL682NQ/0/da"><img src="http://feedads.g.doubleclick.net/~a/PWbGWtpMKoFw3-GFDGp0lL682NQ/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/PWbGWtpMKoFw3-GFDGp0lL682NQ/1/da"><img src="http://feedads.g.doubleclick.net/~a/PWbGWtpMKoFw3-GFDGp0lL682NQ/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/394C9pwhEN4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/08/30/rails-3-0-release/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/08/30/rails-3-0-release/</feedburner:origLink></item>
		<item>
		<title>H8ball, the HTTP Status 8-ball</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/-qXFpdFJWkA/</link>
		<comments>http://metautonomo.us/2010/08/26/h8ball-the-http-status-8-ball/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 23:41:45 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[geekery]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=521</guid>
		<description><![CDATA[So, there&#8217;s this pointless little side project I did last week. It&#8217;s called h8ball, and it&#8217;s completely stupid. I&#8217;ll say it first so you don&#8217;t have to. Still, I figured I&#8217;d make a quick post about it, all the same, just so you&#8217;d know how something so random and stupid came to be. We have [...]]]></description>
			<content:encoded><![CDATA[<p>So, there&#8217;s this pointless little side project I did last week. It&#8217;s called <a href="http://h8ball.com">h8ball</a>, and it&#8217;s completely stupid. I&#8217;ll say it first so you don&#8217;t have to. Still, I figured I&#8217;d make a quick post about it, all the same, just so you&#8217;d know how something so random and stupid came to be.<br />
<span id="more-521"></span><br />
We have a really fun group of geeks  at <a href="http://missiondata.com">Mission Data</a>, and occasionally we get into silly discussions that only a geek could find amusing. One such discussion happened when <a href="http://twitter.com/stasiaweb">Stasia</a> commented that she was tired of seeing 500 error status codes from a web application she was testing out. <a href="http://twitter.com/sfyelton">Steven</a> responded that she had better learn to respect the status codes, or he&#8217;d hit her with a 403 (forbidden) error, instead.</p>
<p>It was then that I pulled up WIkipedia&#8217;s <a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes">list</a> of HTTP status codes and started reading through them. Taken out of context, some of them could be downright amusing, and I commented that many of them sounded like the kinds of <a href="http://en.wikipedia.org/wiki/Magic_8-Ball#Standard_answers">answers</a> you get from a Magic 8-ball. That got some chuckles, so I spent 10 minutes hacking a quick app together that would return a random status code.</p>
<p>Then it got out of hand. That night I started working on twitter oath integration, the next night, some basic layout, and the next, comments. Anyway, the completely useless end result is at <a href="http://h8ball.com">http://h8ball.com</a> for your mild amusement. At least I can say I got to play a bit with Twitter integration, which I&#8217;d been putting off until now.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/bVECesu5GATRBGIyc-eoaGiS8g4/0/da"><img src="http://feedads.g.doubleclick.net/~a/bVECesu5GATRBGIyc-eoaGiS8g4/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/bVECesu5GATRBGIyc-eoaGiS8g4/1/da"><img src="http://feedads.g.doubleclick.net/~a/bVECesu5GATRBGIyc-eoaGiS8g4/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/-qXFpdFJWkA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/08/26/h8ball-the-http-status-8-ball/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/08/26/h8ball-the-http-status-8-ball/</feedburner:origLink></item>
		<item>
		<title>Why MetaWhere 0.9.2 raises errors (and why you’ll thank me later)</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/JzHzxqviadc/</link>
		<comments>http://metautonomo.us/2010/08/26/why-metawhere-0-9-2-raises-errors-and-why-youll-thank-me-later/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 11:00:24 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[meta_where]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=511</guid>
		<description><![CDATA[If you updated MetaWhere recently, and your application started raising MetaWhereInAssociationErrors, I&#8217;m sorry. But not too sorry. Because that error probably saved you from running into strange, confusing problems later. Let me explain. The bug hunt If you&#8217;re a typical MetaWhere user, you&#8217;ve gotten into the habit of specifying your conditions with the improved syntax [...]]]></description>
			<content:encoded><![CDATA[<p>If you updated MetaWhere recently, and your application started raising <tt>MetaWhereInAssociationError</tt>s, I&#8217;m sorry. But not <em>too</em> sorry. Because that error probably saved you from running into strange, confusing problems later. Let me explain.<br />
<span id="more-511"></span></p>
<h4>The bug hunt</h4>
<p>If you&#8217;re a typical MetaWhere user, you&#8217;ve gotten into the habit of specifying your conditions with the improved syntax pretty quickly, and they are almost second nature to you now. They certainly were to me, at least.</p>
<p>So much so, in fact, that in my last project, without thinking, I had declared this in an association:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#5A0A0A; font-weight:bold;">has_many</span> <span style="color:#ff3333; font-weight:bold;">:optional_photos</span>, <span style="color:#ff3333; font-weight:bold;">:class_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Photo&quot;</span>,
                           <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:subtype.<span style="color:#9900CC;">matches</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'optional%'</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p></code></p>
<p>This was a silly mistake on my part, but I&#8217;d gotten so used to using MetaWhere it didn&#8217;t hit me until later, when none of my optional photos were showing up. I was confused for a moment. I checked the log to see this query:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span> COUNT<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">*</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> count_id
<span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #ff0000;">`assets`</span> <span style="color: #993333; font-weight: bold;">WHERE</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`assets`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`type`</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'Photo'</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`assets`</span><span style="color: #66cc66;">.</span>project_id <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">2</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">`assets`</span><span style="color: #66cc66;">.</span><span style="color: #ff0000;">`subtype`</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">'optional%'</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>
  <span style="color: #993333; font-weight: bold;">AS</span> subquery</pre></div></div>

<p></code></p>
<p>Did you spot the problem? My intended LIKE query was being converted to an = query. This happens in <tt>activerecord/lib/active_record/reflection.rb</tt>, in Association#dependent_conditions:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> dependent_conditions<span style="color:#006600; font-weight:bold;">&#40;</span>record, base_class, extra_conditions<span style="color:#006600; font-weight:bold;">&#41;</span>
  dependent_conditions = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  dependent_conditions <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;#{primary_key_name} = #{record.send(name).send(:owner_quoted_id)}&quot;</span>
  dependent_conditions <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;#{options[:as]}_type = '#{base_class.name}'&quot;</span> <span style="color:#9966CC; font-weight:bold;">if</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:as</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  dependent_conditions <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> klass.<span style="color:#9900CC;">send</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:sanitize_sql</span>, options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:conditions</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:conditions</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  dependent_conditions <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> extra_conditions <span style="color:#9966CC; font-weight:bold;">if</span> extra_conditions
  dependent_conditions = dependent_conditions.<span style="color:#9900CC;">collect</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>where<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">&quot;(#{where})&quot;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot; AND &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  dependent_conditions = dependent_conditions.<span style="color:#CC0066; font-weight:bold;">gsub</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'@'</span>, <span style="color:#996600;">'<span style="color:#000099;">\@</span>'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  dependent_conditions
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p></code></p>
<p>The important part is the line that calls <tt>sanitize_sql</tt> on options[:conditions]. That method converts hashes to standard equality conditions.</p>
<h4>Why this matters</h4>
<p><em>&#8220;So, why not make sanitize_sql understand MetaWhere conditions? Isn&#8217;t that the solution?&#8221;</em> I&#8217;m glad you (okay, <em>I</em>) asked. Because it&#8217;s <strong>completely reasonable</strong> for the existing behavior to occur in associations.</p>
<p>One of the key reasons you would choose to use an association over a plain instance method to access associated records is that they bake in some special magic that allows you to create new instances of the associated model. For instance, to build a new instance of a comment associated with the first article:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">ruby<span style="color:#006600; font-weight:bold;">-</span>1.9.2<span style="color:#006600; font-weight:bold;">-</span>p0 <span style="color:#006600; font-weight:bold;">&gt;</span> Article.<span style="color:#5A0A0A; font-weight:bold;">first</span>.<span style="color:#9900CC;">comments</span>.<span style="color:#9900CC;">build</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:body</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'hey!'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
 <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#008000; font-style:italic;">#&lt;Comment id: nil, article_id: 1, body: &quot;hey!&quot;, created_at: nil,</span>
      updated_at: nil<span style="color:#006600; font-weight:bold;">&gt;</span></pre></div></div>

<p></code></p>
<p>Let&#8217;s assume, for a moment, a has_many association that looks like this, though (<strong>note:</strong> Don&#8217;t do this. MetaWhere won&#8217;t let you now, anyway):</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#5A0A0A; font-weight:bold;">has_many</span> <span style="color:#ff3333; font-weight:bold;">:old_comments</span>,
         <span style="color:#ff3333; font-weight:bold;">:class_name</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;Comment&quot;</span>,
         <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:created_at.<span style="color:#9900CC;">lt</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;2009-01-01&quot;</span>.<span style="color:#9900CC;">to_time</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p></code></p>
<p>What would constitute the &#8220;correct&#8221; way to create a new record, now? To set the created_at value to 1 second before New Year&#8217;s Day, 2009? The beginning of time? It doesn&#8217;t really make any sense.</p>
<p>This is why MetaWhere will now check whether you are trying to use MetaWhere conditions in an association macro, and raise the error. Better to stop in your tracks before you go too far down that road. That road leads to madness.</p>
<h4>If not an association, then what?</h4>
<p>In my case, since I was only using that association to load optional photos, and not create them, I went with an instance method:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> optional_photos
  assets.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:type</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Photo'</span>, <span style="color:#ff3333; font-weight:bold;">:subtype</span>.<span style="color:#9900CC;">matches</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'optional%'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p></code></p>
<p>If you weren&#8217;t intending to find only those objects associated with an instance, then you weren&#8217;t looking for an association in the first place, anyway &#8212; use a scope instead.</p>
<p>Of course, the error message will tell you as much:</p>
<blockquote><p>
MetaWhere::MetaWhereInAssociationError: The :lame_comments association  has a MetaWhere::Column in its :conditions. If you actually needed to access conditions other than equality, then you most likely meant to set up a scope or method, instead. Associations only work with standard equality conditions, since they can be used to create records as well.
</p></blockquote>

<p><a href="http://feedads.g.doubleclick.net/~a/U4yulI5_vJ7MECvIahBp-hhk9hU/0/da"><img src="http://feedads.g.doubleclick.net/~a/U4yulI5_vJ7MECvIahBp-hhk9hU/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/U4yulI5_vJ7MECvIahBp-hhk9hU/1/da"><img src="http://feedads.g.doubleclick.net/~a/U4yulI5_vJ7MECvIahBp-hhk9hU/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/JzHzxqviadc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/08/26/why-metawhere-0-9-2-raises-errors-and-why-youll-thank-me-later/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/08/26/why-metawhere-0-9-2-raises-errors-and-why-youll-thank-me-later/</feedburner:origLink></item>
		<item>
		<title>Coder Archetypes: The Line Worker and the Artist</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/1codSXyqdLw/</link>
		<comments>http://metautonomo.us/2010/08/04/coder-archetypes-the-line-worker-and-the-artist/#comments</comments>
		<pubDate>Wed, 04 Aug 2010 11:30:09 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[philosophy]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=492</guid>
		<description><![CDATA[It&#8217;s no secret that there are two types of coders out there. The first went out and got a CS degree because someone once told him that there&#8217;s a good future in anything having to do with computers. We&#8217;ll call him the Line Worker. The second has a passion for coding. His degree might not [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s no secret that there are two types of coders out there. The first went out and got a CS degree because someone once told him that there&#8217;s a good future in anything having to do with computers. We&#8217;ll call him the Line Worker. The second has a passion for coding. His degree might not be in CS. He may not even have a degree (oh, the <em>humanity</em>!), but he <strong>loves</strong> to code. He&#8217;s an Artist. It&#8217;s not just a day job for him. Companies who don&#8217;t seek out and retain Artists are doomed.<br />
<span id="more-492"></span></p>
<h4>Why?</h4>
<p>Line Workers build widgets. Someone hands them a blueprint<a href="#footnote1"><sup>1</sup></a> for a widget. The blueprint tells them how tall and how wide the widget should be. It tells them that the widget should rotate in a counter-clockwise direction and be made of a material strong enough to withstand 25 pounds of pressure. The Line Worker diligently creates the widget that is requested of him, applying design patterns as appropriate (if his employer is lucky). Enterprisey companies <em>looove</em> Line Workers, because they churn out lines of code like nobody&#8217;s business.</p>
<p>Artists find widget building tedious and repetitive. They push back when the blueprint they receive makes no sense, and they recognize the similarities between that blueprint and 10 others just like it in the past 2 months. Instead of building widgets, they build a widget builder, so that they never have to build another widget. As a result, they churn out less lines of code. The enterprisey company sees them as difficult, unproductive primadonnas. They fail to recognize the value proposition of a coder who wants to code himself out of a boring job.</p>
<p>The result? Companies that hire Line Workers assume creativity is the realm of someone in another department, someone who often doesn&#8217;t even know what might be possible via code, unless it&#8217;s shown to them. They&#8217;re building a house, and they hire an architect who doesn&#8217;t understand structural integrity and a color-blind interior designer.</p>
<p>So, how does a company attract and nurture Artists?</p>
<h4>Getting Started</h4>
<p>For starters, Artists need room for creative expression. If the only place your Artist can get creative is in his code comments, because everything else about the application has already been rigidly defined, then prepare yourself for some scathing comments. Bring him in early, while the ideas for your application are still being fleshed out. Besides showing the Artist that you value what he brings to the table, this will also benefit the project in tangible ways:</p>
<ol>
<li>The Artist will give your client more bang for his project&#8217;s budget. He&#8217;ll identify when something that <em>seems</em> simple is anything but, and he&#8217;ll identify when something adds a lot of value for very little effort. He will educate your clients and your sales team while simultaneously showcasing your in-house talent.</li>
<li>Letting your Artist in on these early meetings will help him better understand what the project pipeline looks like. This will allow him to more effectively prioritize tasks, and identify upcoming cases for code reuse, letting him know when it will pay off to create those widget-builders he&#8217;s known for. You <em>are</em> hiring <a href="http://37signals.com/svn/posts/1430-hire-managers-of-one">managers of one</a>, aren&#8217;t you?</li>
</ol>
<h4>Ongoing Process</h4>
<p>The term &#8220;Agile Development&#8221; has been overused and abused. Many companies are &#8220;agile&#8221; in word but not deed, and still others embrace the term as synonymous with &#8220;our developers do code sprints&#8221; but still go about defining project requirements the same old waterfall way they always have. I prefer to describe the ideal development process as &#8220;Common Sense.&#8221;</p>
<p><strong>Example:</strong> If you&#8217;ve spent 40 hours (remember, when meetings are involved, attendees x duration = hours) describing functionality without at least having some wireframes and some proof-of-concept functionality, <em>you&#8217;re doing it wrong</em>. Don&#8217;t keep your Artist in the dark. In particular, as your designers (if the Artist isn&#8217;t also your designer) build out those wireframes, they should work closely with the Artist. He will quickly recognize the patterns they&#8217;re repeating over and over, and save them hours of effort by writing code to do it for them.</p>
<h4>Tools</h4>
<p>Choose a language and framework which gives your Artist the most joy. An Artist will put in extra hours working when work feels more like play.</p>
<p>I&#8217;ve tried my hand at at many languages over the past 26 years, and a nice helping of frameworks as well. I&#8217;ve never enjoyed development more than since I started working with <a href="http://ruby-lang.org">Ruby</a> and, by extension, <a href="http://rubyonrails.org">Ruby on Rails</a>. When possible, I approach projects using these tools because I find they bring me the most joy. Why? Because Ruby&#8217;s flexible metaprogramming capabilities allow me to make boring projects interesting. If it&#8217;s boring and repetitive to write certain code, there&#8217;s a high probability that writing code <em>to write that code</em> is a more interesting (and reusable) problem to solve.</p>
<p>Now, Ruby might not be a good fit for your typical project, or your Artists. I&#8217;m not suggesting that you use a screwdriver to drive in nails. Just find a screwdriver that makes your Artist happy, and when someone asks you to hang a picture on the wall, prefer screws to nails if given the choice.</p>
<p><strong>One final note: choose a language that gives your Artist enough rope to hang himself, and trust your Artist not to end up a pi&ntilde;ata.</strong> Make sure your tool of choice provides enough flexibility for your Artist to really express himself, and you (and your Artist) will be glad you did.</p>
<p><small><a name="footnote1">1</a> In our industry they&#8217;re called &#8220;functional specifications.&#8221; Why, I don&#8217;t know, because they&#8217;re about as dysfunctional a concept as I&#8217;ve ever seen.</small></p>

<p><a href="http://feedads.g.doubleclick.net/~a/Wbwptad6JoCTIidx4Nq05d8a6pI/0/da"><img src="http://feedads.g.doubleclick.net/~a/Wbwptad6JoCTIidx4Nq05d8a6pI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Wbwptad6JoCTIidx4Nq05d8a6pI/1/da"><img src="http://feedads.g.doubleclick.net/~a/Wbwptad6JoCTIidx4Nq05d8a6pI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/1codSXyqdLw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/08/04/coder-archetypes-the-line-worker-and-the-artist/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/08/04/coder-archetypes-the-line-worker-and-the-artist/</feedburner:origLink></item>
		<item>
		<title>MetaWhere updates, in more detail</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/zakEsUZSzw4/</link>
		<comments>http://metautonomo.us/2010/07/26/metawhere-updates-in-more-detail/#comments</comments>
		<pubDate>Tue, 27 Jul 2010 00:19:32 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[meta_where]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=471</guid>
		<description><![CDATA[With Rails 3.0 RC released, I decided I&#8217;d better step up the pace on the promise I made to cover recent updates to MetaWhere and MetaSearch in more detail prior to Rails 3 final. Tonight, I&#8217;d like to spend some time on detailing the changes to MetaWhere since 0.3.3. Smarter Order Clauses This one is [...]]]></description>
			<content:encoded><![CDATA[<p>With <a href="http://weblog.rubyonrails.org/2010/7/26/rails-3-0-release-candidate">Rails 3.0 RC released</a>, I decided I&#8217;d better step up the pace on the <a href="http://metautonomo.us/2010/06/30/scoping-searches-with-metasearch/">promise</a> I made to cover recent updates to MetaWhere and MetaSearch in more detail prior to Rails 3 final. Tonight, I&#8217;d like to spend some time on detailing the changes to MetaWhere since 0.3.3.<br />
<span id="more-471"></span></p>
<h4>Smarter Order Clauses</h4>
<p>This one is pretty simple. ActiveRecord 3.0 query syntax normally dictates that you supply a valid SQL string to the <tt>order</tt> method, like so:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Article.<span style="color:#9900CC;">joins</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comments</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">order</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'comments.created_at desc'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;SELECT &quot;</span>articles<span style="color:#996600;">&quot;.* FROM &quot;</span>articles<span style="color:#996600;">&quot;
   INNER JOIN &quot;</span>comments<span style="color:#996600;">&quot; ON &quot;</span>comments<span style="color:#996600;">&quot;.&quot;</span>article_id<span style="color:#996600;">&quot; = &quot;</span>articles<span style="color:#996600;">&quot;.&quot;</span>id<span style="color:#996600;">&quot;
   ORDER BY comments.created_at desc&quot;</span></pre></div></div>

<p></code></p>
<p>With MetaWhere, you can supply your order clauses in Ruby, instead of SQL. Since you&#8217;re supplying hashes, the same inference about table names is in effect here as in your where clauses, meaning that multiple joins of the same table will reference the proper table alias automatically, and (of course) you can use autojoin.</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Article.<span style="color:#9900CC;">order</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comments</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:created_at</span>.<span style="color:#9900CC;">desc</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">autojoin</span>.<span style="color:#9900CC;">to_sql</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;SELECT &quot;</span>articles<span style="color:#996600;">&quot;.* FROM &quot;</span>articles<span style="color:#996600;">&quot;
   INNER JOIN &quot;</span>comments<span style="color:#996600;">&quot; ON &quot;</span>comments<span style="color:#996600;">&quot;.&quot;</span>article_id<span style="color:#996600;">&quot; = &quot;</span>articles<span style="color:#996600;">&quot;.&quot;</span>id<span style="color:#996600;">&quot;
   ORDER BY &quot;</span>comments<span style="color:#996600;">&quot;.&quot;</span>created_at<span style="color:#996600;">&quot; DESC&quot;</span></pre></div></div>

<p></code></p>
<p>Speaking of table aliasing&#8230;</p>
<h4>Multiple Self-referencing Join Support</h4>
<p>Let&#8217;s say you have a model called Person. A person belongs_to a parent and has_many children, both of which are also instances of Person (unless biology has changed significantly since when I learned it). Now, you want to search your people for people whose grandchildren are named &#8220;Jacob&#8221; (this is yanked straight from the MetaWhere test suite by the way):</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Person.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:children</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:children <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Jacob'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">autojoin</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;SELECT &quot;</span>people<span style="color:#996600;">&quot;.* FROM &quot;</span>people<span style="color:#996600;">&quot;
   INNER JOIN &quot;</span>people<span style="color:#996600;">&quot; &quot;</span>children_people<span style="color:#996600;">&quot;
     ON &quot;</span>children_people<span style="color:#996600;">&quot;.&quot;</span>parent_id<span style="color:#996600;">&quot; = &quot;</span>people<span style="color:#996600;">&quot;.&quot;</span>id<span style="color:#996600;">&quot;
   INNER JOIN &quot;</span>people<span style="color:#996600;">&quot; &quot;</span>children_people_2<span style="color:#996600;">&quot;
     ON &quot;</span>children_people_2<span style="color:#996600;">&quot;.&quot;</span>parent_id<span style="color:#996600;">&quot; = &quot;</span>children_people<span style="color:#996600;">&quot;.&quot;</span>id<span style="color:#996600;">&quot;
   WHERE (&quot;</span>children_people_2<span style="color:#996600;">&quot;.&quot;</span>name<span style="color:#996600;">&quot; = 'Jacob')&quot;</span></pre></div></div>

<p></code></p>
<p>As you can see, MetaWhere takes care of figuring out which table alias you want your condition to apply to. This works in both directions, so, for example, assuming a Person belongs_to both a father and mother, this will let you get a person whose father is named Abraham and mother is named Sarah:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Person.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:father</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Abraham'</span><span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#ff3333; font-weight:bold;">:mother</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:name <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'Sarah'</span><span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p></code></p>
<p>Very readable.</p>
<h4>Opt-in Operators</h4>
<p>Overriding operators is a very polarizing thing. Some people get really bent out of shape over it, claiming it&#8217;s a surefire way to earn yourself a one-way ticket to coder hell. Personally, I think that if the overrides suit your problem domain, then go for it. Still, I can respect the concern that an override on Symbol operators stands a good chance of conflicting with someone else&#8217;s code, so they are off by default in MetaWhere. If you want to use operators in your conditions (such as <tt>:created_at >= 1.week.ago</tt> instead of <tt>:created_at.gteq => 1.week.ago</tt> you will need to add <strong><tt>MetaWhere.operator_overload!</tt></strong> to an initializer in your application.</p>
<p>That&#8217;s it for now! I hope you&#8217;re enjoying Rails 3 as much as I am, and I hope that MetaWhere proves to be a useful tool in your Rails 3 development!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/edJ-RWwkd0T9nS0qUsvOneZqRR0/0/da"><img src="http://feedads.g.doubleclick.net/~a/edJ-RWwkd0T9nS0qUsvOneZqRR0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/edJ-RWwkd0T9nS0qUsvOneZqRR0/1/da"><img src="http://feedads.g.doubleclick.net/~a/edJ-RWwkd0T9nS0qUsvOneZqRR0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/zakEsUZSzw4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/07/26/metawhere-updates-in-more-detail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/07/26/metawhere-updates-in-more-detail/</feedburner:origLink></item>
		<item>
		<title>MetaWhere 0.5.2 – Debug your SQL</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/EIpa1vyYock/</link>
		<comments>http://metautonomo.us/2010/07/09/metawhere-0-5-2-debug-your-sql/#comments</comments>
		<pubDate>Sat, 10 Jul 2010 03:09:51 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[meta_where]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=465</guid>
		<description><![CDATA[I just pushed version 0.5.2 of MetaWhere after some discussion on the Rails core mailing list, adding the debug_sql method. What&#8217;s the difference between debug_sql and to_sql, you ask? While the to_sql method is a handy way to show your query, but as I&#8217;ve written about before, it has its shortcomings. When your query is [...]]]></description>
			<content:encoded><![CDATA[<p>I just pushed version 0.5.2 of MetaWhere after some <a href="http://groups.google.com/group/rubyonrails-core/browse_thread/thread/cd51596294dbd897">discussion on the Rails core mailing list</a>, adding the <tt>debug_sql</tt> method. What&#8217;s the difference between <tt>debug_sql</tt> and <tt>to_sql</tt>, you ask?<br />
<span id="more-465"></span><br />
While the <tt>to_sql</tt> method is a handy way to show your query, but <a href="http://metautonomo.us/2010/05/11/activerecord-relation-vs-arel/#to_sql">as I&#8217;ve written about before</a>, it has its shortcomings. When your query is going to eager load some records and has conditions referencing the eager loaded tables, ActiveRecord changes its generated query, but to_sql is none the wiser. Enter debug_sql:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">ruby<span style="color:#006600; font-weight:bold;">-</span>1.9.2<span style="color:#006600; font-weight:bold;">-</span>head <span style="color:#006600; font-weight:bold;">&gt;</span> Article.<span style="color:#9900CC;">includes</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comments</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comments</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:body <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'hey'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_sql</span>
 <span style="color:#006600; font-weight:bold;">=&gt;</span> SELECT <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#006600; font-weight:bold;">*</span> FROM <span style="color:#996600;">&quot;articles&quot;</span> WHERE <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;body&quot;</span> = <span style="color:#996600;">'hey'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;">#</span>
<span style="color:#008000; font-style:italic;"># LIES!!!</span>
<span style="color:#008000; font-style:italic;">#</span>
ruby<span style="color:#006600; font-weight:bold;">-</span>1.9.2<span style="color:#006600; font-weight:bold;">-</span>head <span style="color:#006600; font-weight:bold;">&gt;</span> Article.<span style="color:#9900CC;">includes</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comments</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">where</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comments</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#123;</span>:body <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'hey'</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">debug_sql</span>
 <span style="color:#006600; font-weight:bold;">=&gt;</span> SELECT <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;id&quot;</span> AS t0_r0, <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;title&quot;</span> AS t0_r1,
           <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;body&quot;</span> AS t0_r2, <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;created_at&quot;</span> AS t0_r3,
           <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;updated_at&quot;</span> AS t0_r4, <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;lookup_id&quot;</span> AS t0_r5,
           <span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;id&quot;</span> AS t1_r0, <span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;article_id&quot;</span> AS t1_r1,
           <span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;body&quot;</span> AS t1_r2, <span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;created_at&quot;</span> AS t1_r3,
           <span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;updated_at&quot;</span> AS t1_r4
    FROM   <span style="color:#996600;">&quot;articles&quot;</span> LEFT OUTER JOIN <span style="color:#996600;">&quot;comments&quot;</span>
           ON <span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;article_id&quot;</span> = <span style="color:#996600;">&quot;articles&quot;</span>.<span style="color:#996600;">&quot;id&quot;</span>
    WHERE  <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;comments&quot;</span>.<span style="color:#996600;">&quot;body&quot;</span> = <span style="color:#996600;">'hey'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#008000; font-style:italic;"># The (ugly) truth!</span></pre></div></div>

<p></code></p>

<p><a href="http://feedads.g.doubleclick.net/~a/IHA02MFaj7Uw6vTqQ_ilLCsDUGA/0/da"><img src="http://feedads.g.doubleclick.net/~a/IHA02MFaj7Uw6vTqQ_ilLCsDUGA/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/IHA02MFaj7Uw6vTqQ_ilLCsDUGA/1/da"><img src="http://feedads.g.doubleclick.net/~a/IHA02MFaj7Uw6vTqQ_ilLCsDUGA/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/EIpa1vyYock" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/07/09/metawhere-0-5-2-debug-your-sql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/07/09/metawhere-0-5-2-debug-your-sql/</feedburner:origLink></item>
		<item>
		<title>Uploadify and Rails 3</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/wW6MPSg63zk/</link>
		<comments>http://metautonomo.us/2010/07/09/uploadify-and-rails-3/#comments</comments>
		<pubDate>Fri, 09 Jul 2010 11:37:58 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=451</guid>
		<description><![CDATA[If you&#8217;re using Uploadify, the nifty jQuery file upload plugin &#8212; which we&#8217;ll forgive for providing all its examples in PHP (*shudder*) &#8212; there&#8217;s a good chance you followed the general pattern outlined by John Nunemaker over at RailsTips. His article describes in detail how to get Flash to play nicely with Rails sessions using [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re using <a href="http://www.uploadify.com/">Uploadify</a>, the nifty jQuery file upload plugin &#8212; which we&#8217;ll forgive for providing all its examples in PHP (*shudder*) &#8212; there&#8217;s a good chance you followed the general pattern <a href="http://railstips.org/blog/archives/2009/07/21/uploadify-and-rails23/">outlined</a> by John Nunemaker over at <a href="http://railstips.org/">RailsTips</a>. His article describes in detail how to get Flash to play nicely with Rails sessions using Rack middleware. Unfortunately, Rails 3 requires a few minor changes to this setup.<br />
<span id="more-451"></span></p>
<h4>In your view</h4>
<p>First up, as before, you&#8217;ll need to tell Uploadify about the name of your application&#8217;s session key. The important change here is where the session key name can now be found: <tt>Rails.application.config.session_options[:key]</tt>.</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #339933;">&lt;%</span> session_key_name <span style="color: #339933;">=</span> Rails.<span style="color: #660066;">application</span>.<span style="color: #660066;">config</span>.<span style="color: #660066;">session_options</span><span style="color: #009900;">&#91;</span><span style="color: #339933;">:</span>key<span style="color: #009900;">&#93;</span> <span style="color: #339933;">%&gt;</span>
  $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#&lt;%= &quot;#{asset_name}_upload&quot; %&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">uploadify</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
      uploader        <span style="color: #339933;">:</span> <span style="color: #3366CC;">'/uploadify/uploadify.swf'</span><span style="color: #339933;">,</span>
      script          <span style="color: #339933;">:</span> <span style="color: #3366CC;">'&lt;%= url_for @project %&gt;'</span><span style="color: #339933;">,</span>
      fileDataName    <span style="color: #339933;">:</span> <span style="color: #3366CC;">'project[&lt;%= &quot;#{asset_name}_attributes&quot; %&gt;][data]'</span><span style="color: #339933;">,</span>
      cancelImg       <span style="color: #339933;">:</span> <span style="color: #3366CC;">'/uploadify/cancel.png'</span><span style="color: #339933;">,</span>
      fileDesc        <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Photo or Video'</span><span style="color: #339933;">,</span>
      fileExt         <span style="color: #339933;">:</span> <span style="color: #3366CC;">'*.mov;*.mp4;*.avi;*.wmv;*.png;*.jpg;*.gif'</span><span style="color: #339933;">,</span>
      auto            <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
      sizeLimit       <span style="color: #339933;">:</span> <span style="color: #339933;">&lt;%=</span> 100.<span style="color: #660066;">megabytes</span> <span style="color: #339933;">%&gt;,</span>
      width           <span style="color: #339933;">:</span> <span style="color: #CC0000;">150</span><span style="color: #339933;">,</span>
      height          <span style="color: #339933;">:</span> <span style="color: #CC0000;">25</span><span style="color: #339933;">,</span>
      hideButton      <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
      wmode           <span style="color: #339933;">:</span> <span style="color: #3366CC;">'transparent'</span><span style="color: #339933;">,</span>
      buttonText      <span style="color: #339933;">:</span> <span style="color: #3366CC;">'Upload'</span><span style="color: #339933;">,</span>
      onComplete      <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>a<span style="color: #339933;">,</span> b<span style="color: #339933;">,</span> c<span style="color: #339933;">,</span> response<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">eval</span><span style="color: #009900;">&#40;</span>response<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#&lt;%= &quot;#{asset_name}_queue&quot; %&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">''</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      queueID         <span style="color: #339933;">:</span> <span style="color: #3366CC;">'noQueueForMePlease'</span><span style="color: #339933;">,</span>
      onProgress      <span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>event<span style="color: #339933;">,</span> queueID<span style="color: #339933;">,</span> fileObj<span style="color: #339933;">,</span> data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span> $<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#&lt;%= &quot;#{asset_name}_queue&quot; %&gt;'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">html</span><span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">percentage</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'%'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      scriptData      <span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #3366CC;">'_http_accept'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'application/javascript'</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">'_method'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'put'</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">'&lt;%= session_key_name %&gt;'</span> <span style="color: #339933;">:</span> encodeURIComponent<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;%= u cookies[session_key_name] %&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
        <span style="color: #3366CC;">'authenticity_token'</span><span style="color: #339933;">:</span> encodeURIComponent<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;%= u form_authenticity_token %&gt;'</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p></code></p>
<h4>A brief aside about my application</h4>
<p>The preceding snippet was taken from an actual application which is a work-in-progress. This application has several file upload &#8220;slots&#8221; that are handled by <tt>accepts_nested_attributes_for</tt> on my Project model, and because the request is always an &#8220;update&#8221; of the parent Project model, it&#8217;s safe for me to hard-code the <tt>_method</tt> as <tt>put</tt>. That may not be the case for you. You will want to examine the following parameters from this example and change them as needed for your application&#8217;s requirements: </p>
<ul>
<li><strong>script</strong>: the URL you want Uploadify to post to. Remember that this can differ depending on whether you want to create or update a record. Thankfully, <tt>url_for</tt> takes this into account when generating a URL from an AR object by checking whether it&#8217;s been persisted or not.</li>
<li><strong>fileDataName</strong>: this should be the same as the file field name generated for your file attribute by the FormBuilder file_field helper.</li>
<li><strong>fileDesc and FileExt</strong>: modify to suit the file extensions you would like to accept. You should still validate at the model level, but this will prevent the file select dialog from allowing selection of other file types.</li>
<li><strong>sizeLimit</strong>: this one should be fairly obvious.</li>
<li><strong>hideButton and wmode</strong>: leave these out if you want the default button to be visible. I&#8217;m replacing it with some text placed behind the (invisible) Flash button.</li>
<li><strong>_http_accept in scriptData and onComplete</strong>: I&#8217;m opting to send along a request for a .js.erb by passing <tt>_http_accept</tt>, and eval the response in onComplete in much the same way as jQuery does when you pass &#8216;script&#8217; to the dataType parameter of jQuery.ajax.</li>
<li><strong>queueID and onProgress</strong>: Uploadify will create a queue with a progress bar below the button by default. I don&#8217;t like this behavior as the queue is too large for the slide-out drawer I&#8217;m using for files. I pass a bogus queueID and set up the onProgress callback to instead replace a percentage number in a div of my choosing.</li>
<li><strong>_method in scriptData</strong>: Since I&#8217;m always posting an update to an existing project (because i&#8217;m using <tt>accepts_nested_attributes_for</tt>) I can safely hardcode <tt>put</tt> here. If you may be creating a new record, you will want to set this conditionally to <tt>post</tt>, based the result of <tt>@myobject.persisted?</tt></li>
</ul>
<h4>The middleware</h4>
<p>Now, you can see we&#8217;re passing the session key and form authenticity token in the above code. The trick is that the session key is stored in a cookie, and Flash doesn&#8217;t know about it. Enter a slightly modified version of John&#8217;s FlashSessionMiddleware.</p>
<p><strong>app/middleware/flash_session_cookie_middleware.rb:</strong><br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rack/utils'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> FlashSessionCookieMiddleware
  <span style="color:#9966CC; font-weight:bold;">def</span> initialize<span style="color:#006600; font-weight:bold;">&#40;</span>app, session_key = <span style="color:#996600;">'_session_id'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@app</span> = app
    <span style="color:#0066ff; font-weight:bold;">@session_key</span> = session_key
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#5A0A0A; font-weight:bold;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'HTTP_USER_AGENT'</span><span style="color:#006600; font-weight:bold;">&#93;</span> =~ <span style="color:#006600; font-weight:bold;">/</span>^<span style="color:#006600; font-weight:bold;">&#40;</span>Adobe<span style="color:#006600; font-weight:bold;">|</span>Shockwave<span style="color:#006600; font-weight:bold;">&#41;</span> Flash<span style="color:#006600; font-weight:bold;">/</span>
      req = <span style="color:#6666ff; font-weight:bold;">Rack::Request</span>.<span style="color:#5A0A0A; font-weight:bold;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
      env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'HTTP_COOKIE'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#0066ff; font-weight:bold;">@session_key</span>,
                             req.<span style="color:#9900CC;">params</span><span style="color:#006600; font-weight:bold;">&#91;</span>@session_key<span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
                           .<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'='</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">freeze</span> <span style="color:#9966CC; font-weight:bold;">unless</span> req.<span style="color:#9900CC;">params</span><span style="color:#006600; font-weight:bold;">&#91;</span>@session_key<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
      env<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'HTTP_ACCEPT'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;#{req.params['_http_accept']}&quot;</span>
                           .<span style="color:#9900CC;">freeze</span> <span style="color:#9966CC; font-weight:bold;">unless</span> req.<span style="color:#9900CC;">params</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'_http_accept'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#0000FF; font-weight:bold;">nil</span>?
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#0066ff; font-weight:bold;">@app</span>.<span style="color:#5A0A0A; font-weight:bold;">call</span><span style="color:#006600; font-weight:bold;">&#40;</span>env<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p></code></p>
<p>Note that aside from setting the <tt>HTTP_COOKIE</tt> header to include the session, we&#8217;re also setting the <tt>HTTP_ACCEPT</tt> header (to allow our Rails app to serve up the .js.erb in a respond_to block). Place this file somewhere handy (I followed his suggestion of app/middleware) and make sure it&#8217;s loaded at Rails startup by adding the following to <tt>config/application.rb</tt> inside the <tt>class Application</tt> block :</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">    <span style="color:#008000; font-style:italic;"># Add additional load paths for your own custom dirs</span>
    <span style="color:#006600; font-weight:bold;">%</span>w<span style="color:#006600; font-weight:bold;">&#40;</span>observers mailers middleware<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#5A0A0A; font-weight:bold;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>dir<span style="color:#006600; font-weight:bold;">|</span>
      config.<span style="color:#9900CC;">autoload_paths</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;#{config.root}/app/#{dir}&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p></code></p>
<h4>Inserting our middleware</h4>
<p>This was the trickiest part. A lot has changed about the Rails boot process between 2.3 and 3.0. While searching for help on getting this set up, I found a bunch of information, most of it bad, on what would work, from different locations for the code to different code altogether. In the end, as it turns out, you can still place the middleware loading code in <tt>config/initializers/session_store.rb</tt>, but it&#8217;s changed quite a bit from Rails 2.3:</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">Rails.<span style="color:#9900CC;">application</span>.<span style="color:#9900CC;">config</span>.<span style="color:#9900CC;">middleware</span>.<span style="color:#9900CC;">insert_before</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#6666ff; font-weight:bold;">ActionDispatch::Session::CookieStore</span>,
  FlashSessionCookieMiddleware,
  Rails.<span style="color:#9900CC;">application</span>.<span style="color:#9900CC;">config</span>.<span style="color:#9900CC;">session_options</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:key</span><span style="color:#006600; font-weight:bold;">&#93;</span>
<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p></code></p>
<p>That&#8217;s it! Hope this helps you avoid the hassles I dealt with in getting Uploadify up and running with Rails 3.</p>

<p><a href="http://feedads.g.doubleclick.net/~a/pQi2w3Zjmwbd1GC25bu1DqVf5jg/0/da"><img src="http://feedads.g.doubleclick.net/~a/pQi2w3Zjmwbd1GC25bu1DqVf5jg/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/pQi2w3Zjmwbd1GC25bu1DqVf5jg/1/da"><img src="http://feedads.g.doubleclick.net/~a/pQi2w3Zjmwbd1GC25bu1DqVf5jg/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/wW6MPSg63zk" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/07/09/uploadify-and-rails-3/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/07/09/uploadify-and-rails-3/</feedburner:origLink></item>
		<item>
		<title>Scoping Searches with MetaSearch</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/qBs8VcD_J2U/</link>
		<comments>http://metautonomo.us/2010/06/30/scoping-searches-with-metasearch/#comments</comments>
		<pubDate>Thu, 01 Jul 2010 00:33:55 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[meta_search]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=446</guid>
		<description><![CDATA[Earlier this month, I released new gems of MetaSearch and MetaWhere. These gems were important personal milestones for me, because with the release of Rails 3 beta 4 and Arel 0.4.0, I was finally able to make a gem release of the work I&#8217;d been putting in on GitHub the past few months. I gave [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this month, <a href="http://metautonomo.us/2010/06/08/metasearch-and-metawhere-0-5-0-released/">I released new gems</a> of <a href="http://metautonomo.us/projects/metasearch/">MetaSearch</a> and <a href="http://metautonomo.us/projects/metawhere/">MetaWhere</a>. These gems were important personal milestones for me, because with the release of Rails 3 beta 4 and Arel 0.4.0, I was finally able to make a gem release of the work I&#8217;d been putting in on GitHub the past few months. I gave a few summary release notes, and then all fell silent on this blog. Part of this is because I&#8217;ve been busy at <a href="http://www.missiondata.com">the office</a>, working on a new iPhone app for a client of ours. Starting tonight, and in preparation for Rails 3 final, I&#8217;m going to cover some of the features in more detail. First up: scoping searches.<br />
<span id="more-446"></span></p>
<h4>Why scope searches?</h4>
<p>While the simplest (and probably most common) use case for MetaSearch is a simple Model.search(params[:search]) in an admin form, there are plenty of cases in which your general user base should be able to search your data, too. The difference between Joe User and an admin, however, is that Joe probably shouldn&#8217;t be able to search every record in your database.</p>
<h4>Well, duh. So how do I do it?</h4>
<p>I&#8217;m glad you asked! :)</p>
<p>So, let&#8217;s say you have a bunch of Projects in your database, and you&#8217;ve already set up a scope to limit visibility. Maybe your scope looks something like this, assuming you&#8217;re using MetaWhere &#8212; you <em>are</em> using MetaWhere, right?</p>
<p><code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;">scope <span style="color:#ff3333; font-weight:bold;">:visible_to_user</span>,
      <span style="color:#CC0066; font-weight:bold;">lambda</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>user<span style="color:#006600; font-weight:bold;">|</span> where<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:user_id</span>.<span style="color:#9900CC;">eq</span> <span style="color:#006600; font-weight:bold;">%</span> user.<span style="color:#9900CC;">id</span> <span style="color:#006600; font-weight:bold;">|</span> <span style="color:#ff3333; font-weight:bold;">:public</span>.<span style="color:#9900CC;">eq</span> <span style="color:#006600; font-weight:bold;">%</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span></pre></div></div>

<p></code></p>
<p>You&#8217;re also probably using something like José Valim&#8217;s excellent <a href="http://github.com/plataformatec/devise">Devise</a> for authentication, so you&#8217;ll have a current_user method. Now it&#8217;s just a matter of filtering your results to projects visible to that user when they do a search.</p>
<p>Prior to 0.5.0, MetaSearch always started searches with a blank slate, which meant that if you wanted to further scope a search, you had to do so by accessing the underlying ActiveRecord::Relation object, like so:</p>
<p><strong>Prior to 0.5.0 (don&#8217;t use now!):</strong><br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#0066ff; font-weight:bold;">@search</span> = Project.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:search</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#0066ff; font-weight:bold;">@projects</span> = <span style="color:#0066ff; font-weight:bold;">@search</span>.<span style="color:#9900CC;">relation</span>.<span style="color:#9900CC;">visible_to_user</span><span style="color:#006600; font-weight:bold;">&#40;</span>current_user<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p></code></p>
<p>That&#8217;s not so bad, but it&#8217;s not very intuitive, either. We can do better. And so we shall. As of MetaSearch 0.5.0:</p>
<p><strong>The new hotness:</strong><br />
<code></p>

<div class="wp_syntax"><div class="code"><pre class="rails" style="font-family:monospace;"><span style="color:#0066ff; font-weight:bold;">@search</span> = Project.<span style="color:#9900CC;">visible_to_user</span><span style="color:#006600; font-weight:bold;">&#40;</span>current_user<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:search</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#0066ff; font-weight:bold;">@projects</span> = <span style="color:#0066ff; font-weight:bold;">@search</span> <span style="color:#008000; font-style:italic;"># Or maybe @search.paginate(...)</span></pre></div></div>

<p></code></p>
<p>Now, we&#8217;re doing what should come naturally &#8212; scoping the search before we ever hand it off to MetaSearch to begin with. It&#8217;s that simple!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/E8kdQUMYzdxMLIy7IfPz0QJUBRI/0/da"><img src="http://feedads.g.doubleclick.net/~a/E8kdQUMYzdxMLIy7IfPz0QJUBRI/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/E8kdQUMYzdxMLIy7IfPz0QJUBRI/1/da"><img src="http://feedads.g.doubleclick.net/~a/E8kdQUMYzdxMLIy7IfPz0QJUBRI/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/qBs8VcD_J2U" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/06/30/scoping-searches-with-metasearch/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/06/30/scoping-searches-with-metasearch/</feedburner:origLink></item>
		<item>
		<title>MetaSearch and MetaWhere 0.5.0 released!</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/XOLHDwLO4jE/</link>
		<comments>http://metautonomo.us/2010/06/08/metasearch-and-metawhere-0-5-0-released/#comments</comments>
		<pubDate>Tue, 08 Jun 2010 23:29:36 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[meta_search]]></category>
		<category><![CDATA[meta_where]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=435</guid>
		<description><![CDATA[With the release of Rails 3.0.0.beta4 and Arel 0.4.0, all of the pieces have come together in gem form to allow a new gem release of both MetaSearch and MetaWhere. I&#8217;m really excited about these releases, as they&#8217;ve been a long time coming. The last MetaSearch gem release was way back in March, while the [...]]]></description>
			<content:encoded><![CDATA[<p>With the <a href="http://weblog.rubyonrails.org/2010/6/8/rails-3-0-beta-4-now-rc-in-days">release</a> of Rails 3.0.0.beta4 and Arel 0.4.0, all of the pieces have come together in gem form to allow a new gem release of both <a href="http://metautonomo.us/projects/metasearch/">MetaSearch</a> and <a href="http://metautonomo.us/projects/metawhere/">MetaWhere</a>.</p>
<p>I&#8217;m really excited about these releases, as they&#8217;ve been a long time coming. The last MetaSearch gem release was way back in March, while the last MetaWhere gem was released in April &#8212; this felt like an eternity in the fast-moving edge Rails world. :) I hope you enjoy the new release, and thanks in advance for <a href="http://metautonomous.lighthouseapp.com/">submitting any bugs</a> you find!</p>
<p>Now, on to what&#8217;s new since the last gem releases&#8230;<br />
<span id="more-435"></span></p>
<h4>MetaSearch 0.5.0</h4>
<p>Changes since 0.3.0 (released March 16th, 2010):</p>
<ul>
<li>Refactoring to make use of Arel predicates in query creation</li>
<li>Addition of validators &#8212; customizable code blocks to determine whether a supplied value is sufficient to use as a search term</li>
<li>Improvements to check_boxes and collection_check_boxes to make them easier to style</li>
<li>Attribute and association exclusion syntax has been updated, and a whitelist version has been added as well (attr_searchable/attr_unsearchable and assoc_searchable/assoc_unsearchable)</li>
<li>Support for custom search methods &#8212; any class method which returns a relation can be used. This, of course, includes scopes</li>
<li>sort_link helper added. Supply a MetaSearch::Builder instance and the name of the attribute to sort on to generate sort links (similar to Searchlogic in Rails 2.3). This works across associations as well.</li>
<li>Multi-level association support. Can go up to 5 levels deep, including the search base.</li>
<li>Searches can be built against a relation with pre-existing where conditions to search across a narrowed scope</li>
</ul>
<h4>MetaWhere 0.5.0</h4>
<p>Changes since 0.3.3 (released April 30th, 2010):</p>
<ul>
<li>Smarter order clauses: <tt>Company.joins(:developers).order(:developers => :salary.desc)</tt></li>
<li>Operator overloads on symbols are now opt-in, via <tt>MetaWhere.operator_overload!</tt></li>
<li>Multiple self-referencing joins are supported</li>
<li>Relations scope new records properly when equality conditions exist (same as stock AR but supporting all equality predicate syntax)</li>
<li>Support for merging relations with a different base</li>
</ul>

<p><a href="http://feedads.g.doubleclick.net/~a/aPAEA0v3s091bOJRRP0psjhPGw8/0/da"><img src="http://feedads.g.doubleclick.net/~a/aPAEA0v3s091bOJRRP0psjhPGw8/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/aPAEA0v3s091bOJRRP0psjhPGw8/1/da"><img src="http://feedads.g.doubleclick.net/~a/aPAEA0v3s091bOJRRP0psjhPGw8/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/XOLHDwLO4jE" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/06/08/metasearch-and-metawhere-0-5-0-released/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/06/08/metasearch-and-metawhere-0-5-0-released/</feedburner:origLink></item>
		<item>
		<title>Arel merge!</title>
		<link>http://feedproxy.google.com/~r/metautonomous/~3/OLubbpifRHU/</link>
		<comments>http://metautonomo.us/2010/05/20/arel-merge/#comments</comments>
		<pubDate>Thu, 20 May 2010 15:01:15 +0000</pubDate>
		<dc:creator>Ernie</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[arel]]></category>
		<category><![CDATA[gem]]></category>
		<category><![CDATA[meta_search]]></category>
		<category><![CDATA[meta_where]]></category>

		<guid isPermaLink="false">http://metautonomo.us/?p=401</guid>
		<description><![CDATA[Using MetaSearch and MetaWhere is about to become simpler, now that most of my Arel changes have been merged into rails/arel. Once a new Arel gem is released, I&#8217;ll make a new gem release of both of my libraries, as well. Thanks to Emilio Tagua (miloops) and Bryan Helmkamp (brynary) for the feedback and eventual [...]]]></description>
			<content:encoded><![CDATA[<p>Using <a href="http://metautonomo.us/projects/metasearch">MetaSearch</a> and <a href="http://metautonomo.us/projects/metawhere">MetaWhere</a> is about to become simpler, now that most of my Arel changes have been <a href="http://github.com/rails/arel/compare/7aff5ac78e...d144b8d5af">merged into rails/arel</a>.  Once a new Arel gem is released, I&#8217;ll make a new gem release of both of my libraries, as well. Thanks to Emilio Tagua (<a href="http://twitter.com/miloops">miloops</a>) and Bryan Helmkamp (<a href="http://twitter.com/brynary">brynary</a>) for the feedback and eventual merge!</p>

<p><a href="http://feedads.g.doubleclick.net/~a/Twbr447OiA5X1VVJTpIwaBCttF0/0/da"><img src="http://feedads.g.doubleclick.net/~a/Twbr447OiA5X1VVJTpIwaBCttF0/0/di" border="0" ismap="true"></img></a><br/>
<a href="http://feedads.g.doubleclick.net/~a/Twbr447OiA5X1VVJTpIwaBCttF0/1/da"><img src="http://feedads.g.doubleclick.net/~a/Twbr447OiA5X1VVJTpIwaBCttF0/1/di" border="0" ismap="true"></img></a></p><img src="http://feeds.feedburner.com/~r/metautonomous/~4/OLubbpifRHU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://metautonomo.us/2010/05/20/arel-merge/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://metautonomo.us/2010/05/20/arel-merge/</feedburner:origLink></item>
	</channel>
</rss>
