<?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>a work on process &#187; rails plugins</title>
	<atom:link href="http://jystewart.net/process/tag/rails-plugins/feed/" rel="self" type="application/rss+xml" />
	<link>http://jystewart.net/process</link>
	<description>notes from another web developer</description>
	<lastBuildDate>Sat, 21 Aug 2010 13:09:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>The Array Argument (aka. *)</title>
		<link>http://jystewart.net/process/2007/02/the-array-argument-aka/</link>
		<comments>http://jystewart.net/process/2007/02/the-array-argument-aka/#comments</comments>
		<pubDate>Fri, 09 Feb 2007 14:47:52 +0000</pubDate>
		<dc:creator>James Stewart</dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[acts_as_locateable]]></category>
		<category><![CDATA[geocoding]]></category>
		<category><![CDATA[patches]]></category>
		<category><![CDATA[rails plugins]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://jystewart.net/process/archives/2007/02/the-array-argument-aka/</guid>
		<description><![CDATA[Wednesday&#8217;s post on acts_as_locateable didn&#8217;t do much to explain what the patch to the plugin&#8217;s methods was doing to allow us to pass extra arguments to ActiveRecord#find. The secret is in the *, or array argument. A normal method will have a fixed number of arguments: def simple_method&#40;first, second, third&#41; puts &#34;#{first} : #{second} : <a href="http://jystewart.net/process/2007/02/the-array-argument-aka/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p><a href="/process/archives/2007/02/extending-acts_as_locateable/">Wednesday&#8217;s post on acts_as_locateable</a> didn&#8217;t do much to explain what the patch to the plugin&#8217;s methods was doing to allow us to pass extra arguments to ActiveRecord#find. The secret is in the <em>*</em>, or array argument.</p>
<p>A normal method will have a fixed number of arguments:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> simple_method<span style="color:#006600; font-weight:bold;">&#40;</span>first, second, third<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{first} : #{second} : #{third}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
simple_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'one'</span>, <span style="color:#996600;">'two'</span>, <span style="color:#996600;">'three'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> one : two : three</pre></div></div>

<p>and sometimes we can develop that by allowing default values for those arguments:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> simple_method<span style="color:#006600; font-weight:bold;">&#40;</span>first, second, third = <span style="color:#996600;">'four'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{first} : #{second} : #{third}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
simple_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'one'</span>, <span style="color:#996600;">'two'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> one : two : four</pre></div></div>

<p>but sometimes we want to allow an arbitrary number of arguments, and that&#8217;s where * (the Array Argument) comes in.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> simple_method<span style="color:#006600; font-weight:bold;">&#40;</span>first, <span style="color:#006600; font-weight:bold;">*</span>others<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{first} : &quot;</span> <span style="color:#006600; font-weight:bold;">+</span> others.<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:#9966CC; font-weight:bold;">end</span>
&nbsp;
simple_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'one'</span>, <span style="color:#996600;">'two'</span>, <span style="color:#996600;">'three'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> one : two : three</pre></div></div>

<p>If you pass in keyed parameters then you will get a hash within the others array:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">def</span> simple_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">*</span>others<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> others.<span style="color:#9900CC;">inspect</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
simple_method<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'one'</span>, <span style="color:#ff3333; font-weight:bold;">:two</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'three'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;one&quot;</span>, <span style="color:#006600; font-weight:bold;">&#123;</span>:two<span style="color:#006600; font-weight:bold;">=&gt;</span><span style="color:#996600;">&quot;three&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#93;</span></pre></div></div>

<p>So in the case of acts_as_locateable, the find_within_radius can take an arbitrary number of parameters to allow for different types of input:</p>
<p>def find_within_radius(radius_in_miles, *args)</p>
<p>All we needed to do to allow in more parameters was to extract our extra arguments which I knew would be grouped together in a Hash, so that the rest of the internals would still get the input they&#8217;re expecting:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># standard_args will be the args input minus any arguments of type Hash</span>
<span style="color:#008000; font-style:italic;"># (our addition to the input)</span>
standard_args = args.<span style="color:#9900CC;">reject</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>arg<span style="color:#006600; font-weight:bold;">|</span> arg.<span style="color:#9900CC;">kind_of</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Hash</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># query_args will then be the first Hash found in the arguments</span>
query_args = <span style="color:#006600; font-weight:bold;">&#40;</span>args <span style="color:#006600; font-weight:bold;">-</span> standard_args<span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">first</span></pre></div></div>

<p>and then we can pass our query_args hash to the <em>find</em> call later on:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">find<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, query_args<span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://jystewart.net/process/2007/02/the-array-argument-aka/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Extending acts_as_locateable</title>
		<link>http://jystewart.net/process/2007/02/extending-acts_as_locateable/</link>
		<comments>http://jystewart.net/process/2007/02/extending-acts_as_locateable/#comments</comments>
		<pubDate>Wed, 07 Feb 2007 21:16:19 +0000</pubDate>
		<dc:creator>James Stewart</dc:creator>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[acts_as_locateable]]></category>
		<category><![CDATA[geocoding]]></category>
		<category><![CDATA[patches]]></category>
		<category><![CDATA[rails plugins]]></category>
		<category><![CDATA[ruby on rails]]></category>

		<guid isPermaLink="false">http://jystewart.net/process/archives/2007/02/extending-acts_as_locateable/</guid>
		<description><![CDATA[There have been quite a few geographically-themed Rails plugins emerging over the past few months and I decided it was time to try out acts_as_locateable. Acts_as_locateable is based on ZipCodeSearch. It loads in a database mapping US zip codes to coordinates and then adds convenience methods to ActiveRecord objects that let you search by distance. <a href="http://jystewart.net/process/2007/02/extending-acts_as_locateable/" class="more-link">More &#62;</a>]]></description>
			<content:encoded><![CDATA[<p>There have been quite a few geographically-themed Rails plugins emerging over the past few months and I decided it was time to try out <a href="http://www.agilewebdevelopment.com/plugins/actsaslocateable">acts_as_locateable</a>.</p>
<p>Acts_as_locateable is based on <a href="http://zipcodesearch.rubyforge.org/">ZipCodeSearch</a>. It loads in a database mapping US zip codes to coordinates and then adds convenience methods to ActiveRecord objects that let you search by distance. eg.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Event.<span style="color:#9900CC;">find_within_radius</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">50</span>, <span style="color:#996600;">'49503'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>will return all events within 50 miles of me.</p>
<p>What the standard plugin doesn&#8217;t allow is the passing in of more search parameters. So if I wanted to limit that search to future events I&#8217;d have to retrieve all the results and iterate over them. In a large system that could be <em>very</em> inefficient.</p>
<p>It turns out it&#8217;s not too hard to hack the plugin to make it accept other ActiveRecord parameters. By just adding a couple more checks to the parameter decoding, and adding an extra argument to the call to find. For my use it turned out to be easier to patch the original than re-open the class and add extra methods, though that would obviously be possible. For anyone who may want it, the patch is:</p>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;">Index: lib/acts_as_locateable.rb
===================================================================
<span style="color: #888822;">--- lib/acts_as_locateable.rb   <span style="">&#40;</span>revision <span style="">29</span><span style="">&#41;</span></span>
<span style="color: #888822;">+++ lib/acts_as_locateable.rb   <span style="">&#40;</span>working copy<span style="">&#41;</span></span>
<span style="color: #440088;">@@ -<span style="">48</span>,<span style="">9</span> +<span style="">48</span>,<span style="">13</span> @@</span>
         # Find instances of the locatable class within radius_in_miles of your target.
         # Target can be specified in a number of ways, see expand_radius_args for options
         def find_within_radius<span style="">&#40;</span>radius_in_miles, *args<span style="">&#41;</span>
<span style="color: #991111;">-          lat, lon = expand_radius_args<span style="">&#40;</span>args<span style="">&#41;</span></span>
<span style="color: #00b000;">+          standard_args = args.reject <span style="">&#123;</span> |arg| arg.kind_of?<span style="">&#40;</span>Hash<span style="">&#41;</span> <span style="">&#125;</span></span>
<span style="color: #00b000;">+          query_args = <span style="">&#40;</span>args - standard_args<span style="">&#41;</span>.first</span>
<span style="color: #00b000;">+          </span>
<span style="color: #00b000;">+          lat, lon = expand_radius_args<span style="">&#40;</span>standard_args<span style="">&#41;</span></span>
<span style="color: #00b000;">+          # query_args = args.find <span style="">&#123;</span> |arg| arg.kind_of?<span style="">&#40;</span>Hash<span style="">&#41;</span> <span style="">&#125;</span></span>
           within_radius_scope<span style="">&#40;</span>radius_in_miles, lat, lon<span style="">&#41;</span> do
<span style="color: #991111;">-            find<span style="">&#40;</span>:all<span style="">&#41;</span></span>
<span style="color: #00b000;">+            find<span style="">&#40;</span>:all, query_args<span style="">&#41;</span></span>
           end
         end</pre></div></div>

<p>Now I can use:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">Event.<span style="color:#9900CC;">find_within_radius</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">50</span>, <span style="color:#996600;">'49503'</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;">&#91;</span><span style="color:#996600;">'starts_at &gt; ?'</span>, <span style="color:#CC00FF; font-weight:bold;">DateTime</span>.<span style="color:#9900CC;">now</span><span style="color:#006600; font-weight:bold;">&#93;</span>, 
	<span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'starts_at'</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>and get much more useful results.</p>
]]></content:encoded>
			<wfw:commentRss>http://jystewart.net/process/2007/02/extending-acts_as_locateable/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
