<?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>TopSecretProject &#187; active-record</title>
	<atom:link href="http://topsecretproject.finitestatemachine.com/tag/active-record/feed/" rel="self" type="application/rss+xml" />
	<link>http://topsecretproject.finitestatemachine.com</link>
	<description>Toby Hede on Technology</description>
	<lastBuildDate>Fri, 07 May 2010 08:37:12 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>CloudKit, pondering the future</title>
		<link>http://topsecretproject.finitestatemachine.com/2009/03/cloudkit-pondering-the-future/</link>
		<comments>http://topsecretproject.finitestatemachine.com/2009/03/cloudkit-pondering-the-future/#comments</comments>
		<pubDate>Tue, 17 Mar 2009 10:58:36 +0000</pubDate>
		<dc:creator>tobyhede</dc:creator>
				<category><![CDATA[Future]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[active-record]]></category>
		<category><![CDATA[cloudkit]]></category>
		<category><![CDATA[github]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[rdbms]]></category>

		<guid isPermaLink="false">http://topsecretproject.finitestatemachine.com/?p=31</guid>
		<description><![CDATA[I ponder the future and trawl the web.
Recently in my travels I found the awesome CloudKit.
CloudKit provides schema-free, auto-versioned, RESTful JSON storage with optional OpenID and OAuth         support, including OAuth Discovery.
Cloudkit is similar in some respects to CouchDB &#8211; date is stored in JSON, access via REST.
I [...]]]></description>
			<content:encoded><![CDATA[<p>I ponder the future and trawl the web.</p>
<p>Recently in my travels I found the awesome <a href="http://getcloudkit.com/">CloudKit</a>.</p>
<blockquote><p>CloudKit provides schema-free, auto-versioned, RESTful JSON storage with optional OpenID and OAuth         support, including OAuth Discovery.</p></blockquote>
<p>Cloudkit is similar in some respects to CouchDB &#8211; date is stored in JSON, access via REST.</p>
<p>I looked at CouchDB in some detail for a project I have in the works and was very impressed with it&#8217;s capabilities, particularly the ability to query the datastore using JavaScript and a Map/Reduce algorithm.</p>
<p>In the end, I have decided that the benefits of persisting* with MySQL (or PostgreSQL) are too great to abandon relational technology just yet &#8211; the Rails ecosystem has such good support for these technologies in Active Record.</p>
<h5>* And yes, pun intended.</h5>
]]></content:encoded>
			<wfw:commentRss>http://topsecretproject.finitestatemachine.com/2009/03/cloudkit-pondering-the-future/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Filtering and Named Scopes</title>
		<link>http://topsecretproject.finitestatemachine.com/2009/03/filtering-and-named-scopes/</link>
		<comments>http://topsecretproject.finitestatemachine.com/2009/03/filtering-and-named-scopes/#comments</comments>
		<pubDate>Sun, 01 Mar 2009 11:33:17 +0000</pubDate>
		<dc:creator>tobyhede</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[active-record]]></category>

		<guid isPermaLink="false">http://topsecretproject.finitestatemachine.com/?p=8</guid>
		<description><![CDATA[I have been delighting in the power of Active Record&#8217;s Named Scopes and recently discovered is a  technique for cleanly adding user-driven filtering to Active Record models using Named Scopes and a little bit of Ruby magic.
Named Scopes provide a clean way of adding finders to your Active Record Models &#8211; collecting complex finder [...]]]></description>
			<content:encoded><![CDATA[<p>I have been delighting in the power of Active Record&#8217;s <strong>Named Scopes</strong> and recently discovered is a  technique for cleanly adding user-driven filtering to Active Record models using Named Scopes and a little bit of Ruby magic.</p>
<p>Named Scopes provide a clean way of adding finders to your Active Record Models &#8211; collecting complex finder logic into granular methods that can then be chained together to perform complex combinations of queries. Named scopes are eminently testable as each defined scope can be tested individually, as well as the actual combinations of scope-chains.</p>
<p>Take the following example from some recent production code:<br />
<code lang="ruby"><br />
named_scope :by_author, lambda { |*args| {:conditions =>; ["author_id = ?", args.first] }}</p>
<p>named_scope :by_state, lambda { |*args| { :conditions => ["state = ?", args.first || "published"]<br />
}}</p>
<p>named_scope :by_date, lambda { |*args| {:conditions => ["published_at BETWEEN ? AND ? OR updated_at BETWEEN ? AND ?", args.first[0], args.first[1] || Time.now, args.first[0], args.first[1] || Time.now]<br />
}}<br />
</code></p>
<p>As you can see, some quite complex logic can be wrapped into the named scopes, including parameters. </p>
<p>The scopes can be chained, which wraps everything into a single query:</p>
<p><code lang="ruby"><br />
Model.by_author(author_id).by_state("published").by_date(10.days.ago)<br />
</code></p>
<p>Once you have your named scopes set up, you can add some magic to dynamically chain them for user-based filtering.</p>
<p>What follows is from Caboose&#8217;s: <a href="http://www.caboo.se/articles/2008/8/26/the-awesomest-filter-and-sort-ever">The awesomest filter and sort ever</a></p>
<p>In the controller I set up some code to grab incoming parameters and pass them to the Model (in this case called BlogPost). </p>
<p><code lang="ruby"><br />
filter_opts = {}<br />
filter_opts[:page] = params[:page] || 1<br />
filter_opts[:author] = params[:user]<br />
filter_opts[:state] = params[:state]<br />
filter_opts[:date] = [start_date, end_date]</p>
<p>@blog_posts = BlogPost.find_by_filter(filter_opts)<br />
</code></p>
<p>I have removed some of the processing logic here, but the idea is that the user selects from a range of filtering options in the User Interface (selecting a date range, for example) and the controller grabs, cleans and validates these as appropriate and passes it through to the model.</p>
<p>The <strong>find_by_filter</strong> method is where all of the magic happens. We add the valid scopes to an array, and then chain them all together using <strong>inject</strong>.</p>
<p><code lang="ruby"><br />
def self.find_by_filter(opts = {})<br />
scopes = []</p>
<p>scopes =>; [:by_author, opts[:author] ] if opts[:author]<br />
scopes => [:by_state, opts[:state]] if opts[:state]<br />
scopes => [:by_date, opts[:date]]  if opts[:date]</p>
<p>order = opts[:order] || "published_at DESC"<br />
page = opts[:page] || 1</p>
<p>scopes.inject(BlogPost) {|model,scope|<br />
model.scopes[scope[0]].call(model, scope[1])<br />
}.paginate(:all, <img src='http://topsecretproject.finitestatemachine.com/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder => order, :page => page)<br />
end<br />
</code></p>
<p>The final line is the magic. Using inject with the model as the accumulator, basically emulates the chained call we saw earlier (by_author.by_state.by_date), but with the added advantage in this instance that only the scopes with the relevant options (defined in <strong>opts</strong>) are called by the find_by_filter.</p>
<p>As you can see, not only are the named scopes chained together, but I am adding paginate for good measure. Records are cleanly paginated</p>
<p>For more information on named scopes see <a href="http://guides.rubyonrails.org/active_record_querying.html#_named_scopes"><br />
Ruby on Rails Active Record Guide</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://topsecretproject.finitestatemachine.com/2009/03/filtering-and-named-scopes/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
