<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kickass Labs &#187; named scope</title>
	<atom:link href="http://www.kickasslabs.com/tag/named-scope/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kickasslabs.com</link>
	<description>We &#9829; code.</description>
	<lastBuildDate>Wed, 28 Dec 2011 16:57:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Better Rails Searching with Named Scopes using Scope Builder</title>
		<link>http://www.kickasslabs.com/2008/12/22/better-rails-searching-with-named-scopes-using-scope-builder/</link>
		<comments>http://www.kickasslabs.com/2008/12/22/better-rails-searching-with-named-scopes-using-scope-builder/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 19:54:16 +0000</pubDate>
		<dc:creator>gabe</dc:creator>
				<category><![CDATA[Rails]]></category>
		<category><![CDATA[named scope]]></category>
		<category><![CDATA[search]]></category>

		<guid isPermaLink="false">http://www.kickasslabs.com/?p=109</guid>
		<description><![CDATA[When it comes writing elegant search code in a Rails app, Named Scopes immediately come to mind.  And for good reason: they&#8217;re a fantastic way to express, well, scopes, for your searches.  In your Person model, you might have named &#8230; <a href="http://www.kickasslabs.com/2008/12/22/better-rails-searching-with-named-scopes-using-scope-builder/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>When it comes writing elegant search code in a Rails app, Named Scopes immediately come to mind.  And for good reason: they&#8217;re a fantastic way to express, well, scopes, for your searches.  In your Person model, you might have named scopes like <code>by_last_name</code>, <code>by_age</code>, and <code>by_sex</code>.  But, what do you do when you want to give your users a search form and let them find people by any combination of last name, age, and sex?</p>
<p><span id="more-109"></span></p>
<p>Well, you might try something like executing each named scope that you have params for and find the intersection of the IDs of all people returned from each named_scope.  That might look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">p1 = Person.<span style="color:#9900CC;">by_last_name</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:last_name</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:last_name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
p2 = Person.<span style="color:#9900CC;">by_age</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:age</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:age</span><span style="color:#006600; font-weight:bold;">&#93;</span>
p3 = Person.<span style="color:#9900CC;">by_sex</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:sex</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:sex</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
people <span style="color:#006600; font-weight:bold;">+</span>= p1 <span style="color:#9966CC; font-weight:bold;">if</span> p1.<span style="color:#9900CC;">length</span> <span style="color:#006600; font-weight:bold;">+</span> p2 <span style="color:#006600; font-weight:bold;">+</span> p3</pre></div></div>

<p>What you really want is <a href="http://github.com/ryanb/scope-builder/tree/master">Ryan Bates&#8217; Scope Builder gem</a>.</p>
<p>Scope Builder lets you &#8220;build up named scopes conditionally.&#8221;  From the README:</p>
<blockquote><p>This gem adds the scope_builder method to all Active Record models. A<br />
builder behaves exactly like any other named scope except that calling<br />
other named scopes on it will alter the builder itself rather than<br />
returning a new named scope.</p></blockquote>
<p>Here&#8217;s some example code using that defines Person.search using named scopes for last_name, age, and sex:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Person <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  named_scope <span style="color:#ff3333; font-weight:bold;">:by_last_name</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>last_name<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:conditions</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'last_name = :last_name'</span>,
        <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:last_name</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; last_name <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span> 
&nbsp;
  named_scope <span style="color:#ff3333; font-weight:bold;">:by_age</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>age<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:conditions</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'age = :age'</span>,
        <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:age</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; age <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span> 
&nbsp;
  named_scope <span style="color:#ff3333; font-weight:bold;">:by_sex</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>sex<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#006600; font-weight:bold;">&#123;</span>
      <span style="color:#ff3333; font-weight:bold;">:conditions</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'sex = :sex'</span>,
        <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#ff3333; font-weight:bold;">:sex</span> =<span style="color:#006600; font-weight:bold;">&amp;</span>gt; sex <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#006600; font-weight:bold;">&#125;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
    scope_builder <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>builder<span style="color:#006600; font-weight:bold;">|</span>
      builder.<span style="color:#9900CC;">by_last_name</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:last_name</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;">:last_name</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      builder.<span style="color:#9900CC;">by_age</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:age</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;">:age</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      builder.<span style="color:#9900CC;">by_sex</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:sex</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;">:sex</span><span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So, now all you need is a People Search form and an action to handle finding the right people.  Here&#8217;s what your search action might look like inside PeopleController:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> search
  <span style="color:#0066ff; font-weight:bold;">@people</span> = Person.<span style="color:#9900CC;">search</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">all</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Important note: When using ScopeBuilder as shown above, you&#8217;ll have to call <code>#all</code> because, in this case, <code>Person.search</code> returns a ScopeBuilder object, not a collection of ActiveRecord Person objects.  To get at the people collection, you call <code>#all</code> on the ScopeBuilder object returned by <code>Person.search</code>.</p>
<p>So, see?  Isn&#8217;t that pretty?  You&#8217;ve got a simple search that will find all the people that meet any all of the attributes passed in from the search form.  Ta da!</p>
<p><a class="a2a_dd a2a_target addtoany_share_save" href="http://www.addtoany.com/share_save#url=http%3A%2F%2Fwww.kickasslabs.com%2F2008%2F12%2F22%2Fbetter-rails-searching-with-named-scopes-using-scope-builder%2F&amp;title=Better%20Rails%20Searching%20with%20Named%20Scopes%20using%20Scope%20Builder" id="wpa2a_2"><img src="http://www.kickasslabs.com/wp-content/plugins/add-to-any/share_save_120_16.png" width="120" height="16" alt="Share"/></a></p>]]></content:encoded>
			<wfw:commentRss>http://www.kickasslabs.com/2008/12/22/better-rails-searching-with-named-scopes-using-scope-builder/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

