<?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/"
	xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"
	xmlns:media="http://search.yahoo.com/mrss/"
>

<channel>
	<title>Retina Technology Blog &#187; software engineering</title>
	<atom:link href="http://www.retina.net/tech/category/software-engineering/feed" rel="self" type="application/rss+xml" />
	<link>http://www.retina.net/tech</link>
	<description>John Adams' views on emerging technologies, software engineering, and various hacks</description>
	<lastBuildDate>Tue, 06 Jul 2010 02:34:39 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<!-- podcast_generator="podPress/8.8" -->
		<copyright>&#xA9;John Adams </copyright>
		<managingEditor>jna@retina.net (John Adams)</managingEditor>
		<webMaster>jna@retina.net(John Adams)</webMaster>
		<category></category>
		<ttl>1440</ttl>
		<itunes:keywords></itunes:keywords>
		<itunes:subtitle></itunes:subtitle>
		<itunes:summary>John Adams' views on emerging technologies, software engineering, and various hacks</itunes:summary>
		<itunes:author>John Adams</itunes:author>
		<itunes:category text="Technology"/>
<itunes:category text="Technology">
  <itunes:category text="Tech News"/>
</itunes:category>
		<itunes:owner>
			<itunes:name>John Adams</itunes:name>
			<itunes:email>jna@retina.net</itunes:email>
		</itunes:owner>
		<itunes:block>No</itunes:block>
		<itunes:explicit>no</itunes:explicit>
		<itunes:image href="http://www.retina.net/tech/wp-content/plugins/podpress/images/powered_by_podpress_large.jpg" />
		<image>
			<url>http://www.retina.net/tech/wp-content/plugins/podpress/images/powered_by_podpress.jpg</url>
			<title>Retina Technology Blog</title>
			<link>http://www.retina.net/tech</link>
			<width>144</width>
			<height>144</height>
		</image>
		<item>
		<title>Unicorn Power</title>
		<link>http://www.retina.net/tech/unicorn-power.html</link>
		<comments>http://www.retina.net/tech/unicorn-power.html#comments</comments>
		<pubDate>Wed, 31 Mar 2010 01:25:51 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[rubyrails]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[twitter]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/unicorn-power.html</guid>
		<description><![CDATA[Ben Sandofsky and I just put a new post on the Twitter Engineering blog about our transition to Unicorn. 
http://engineering.twitter.com/2010/03/unicorn-power.html
]]></description>
			<content:encoded><![CDATA[<p>Ben Sandofsky and I just put a new post on the Twitter Engineering blog about our transition to Unicorn. </p>
<p><a href="http://engineering.twitter.com/2010/03/unicorn-power.html">http://engineering.twitter.com/2010/03/unicorn-power.html</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/unicorn-power.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Memcached and MySQL &#8211; What good is it?</title>
		<link>http://www.retina.net/tech/memcached-and-mysql-what-good-is-it.html</link>
		<comments>http://www.retina.net/tech/memcached-and-mysql-what-good-is-it.html#comments</comments>
		<pubDate>Sun, 17 May 2009 19:56:42 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[peformance]]></category>
		<category><![CDATA[social networking]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[systems administration]]></category>
		<category><![CDATA[memcache]]></category>
		<category><![CDATA[Relational database]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=222</guid>
		<description><![CDATA[I posted this in response to a post on GigaOM, but it was such a long comment, I felt that it was worthy as a post on it&#8217;s own.

The workloads of social networking sites fall mostly into the &#8216;read lots, write once&#8217; class (most of the web exists within this paradigm.) Regardless of the database [...]]]></description>
			<content:encoded><![CDATA[<p>I posted this in response to <a href="http://gigaom.com/2009/05/17/memcached-and-an-ailing-mysql/">a post on GigaOM</a>, but it was such a long comment, I felt that it was worthy as a post on it&#8217;s own.<br />
</em></p>
<p>The workloads of <a id="aptureLink_5gGWByWM0M" href="http://en.wikipedia.org/wiki/Social%20Networking">social networking</a> sites fall mostly into the &#8216;read lots, write once&#8217; class (most of the web exists within this paradigm.) Regardless of the database company that&#8217;s responsible for the software, the main idea in scaling this read heavy workload is to remove the burden from the database and move it to distributed memory stores. </p>
<p>As an engineer, you want applications to pull from the same cache pool to reduce I/O pressure. To ensure that every machine isn&#8217;t replicating data in individual caches, you have to go distributed. That&#8217;s the win with memcached.</p>
<p>Putting a distributed cache between the application and the database increases performance and shares data across your application servers, something that the database cannot do on it&#8217;s own. The database has on-disk and in memory caching, but eventually you&#8217;ll run out of memory on a single host if your working set exceeds the host&#8217;s memory.</p>
<p>Memcached also covers up replication lag (MySQL is terrible at replication, Oracle not so much) in large environments by putting data into the distributed cache (Write-through caching) before the slave database has finished it&#8217;s writing. Data is available immediately to clients, before the replication has completed. </p>
<p>It will also provide a large amount of savings when you&#8217;re constantly executing that O(n x m) query to find out who is friends with whom on your social networking site. </p>
<p>This comes with a cost, though. Relational database functions, like joining across large data sets, and atomic operations, become very difficult to execute. Memcached becomes the central server, and there is always a fear that an important key will drop out of cache because of a random eviction. </p>
<p>It&#8217;s not without risk, either. Dependence on the cache can hurt you severely if lots of memcached servers fail (and they do fail), Leaving you in a &#8216;cold cache&#8217; situation where it can take hours to repopulate your working set back into the cache pool. </p>
<p>Don&#8217;t question MySQL&#8217;s performance &#8212; relational databases are great, but they are not the only solution to storage problems. the two problems that are being solved here are, highly orthogonal. </p>
<p>I&#8217;d also like to state that the majority of alternate key-value store databases <a href="http://www.metabrew.com/article/anti-rdbms-a-list-of-distributed-key-value-stores/">listed in Richard Jones&#8217; article </a> and in <a href="http://randomfoo.net/2009/04/20/some-notes-on-distributed-key-stores">Lenoard Lin&#8217;s</a> blog are really not ready for high production loads (with maybe the exception of Tokyo Cabinet, HDFS,  and Cassandra).  There is still a ton of &#8217;secret sauce&#8217; the large sites are keeping quiet about in order to make these into effective data stores. </p>
<p>Lin states this in his review as well: &#8220;Your comfort-level running in prod may vary, but for most sane people, I doubt you’d want to.&#8221;</p>
<p>Tread lightly. </p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/memcached-and-mysql-what-good-is-it.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Announcing mod_memcache_block</title>
		<link>http://www.retina.net/tech/announcing-mod_memcache_block.html</link>
		<comments>http://www.retina.net/tech/announcing-mod_memcache_block.html#comments</comments>
		<pubDate>Thu, 07 May 2009 20:29:00 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[application security]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[module]]></category>
		<category><![CDATA[security]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=216</guid>
		<description><![CDATA[I&#8217;m announcing the release of mod_memcache_block, a distributed IP blocking system for Apache, with rate limiting based on HTTP request code.
For many years I&#8217;ve had a need for a module like this &#8212; A distributed blocking system which could operate across large web serving clusters and register hits in a central store. With rate limiting, [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m announcing the release of mod_memcache_block, a distributed IP blocking system for Apache, with rate limiting based on HTTP request code.</p>
<p>For many years I&#8217;ve had a need for a module like this &#8212; A distributed blocking system which could operate across large web serving clusters and register hits in a central store. With rate limiting, incrementing counters on a single host is fairly useless when you have hundreds of servers behind a load balancer.</p>
<p>An attacker could hit many machines within the limit period before being detected, because there would be no central count. By keeping the counts in a memcache pool, all servers share the same data.</p>
<p>It won&#8217;t defend against attacks coming from random proxy addresses (say, Tor), and might unfairly count hundreds of users who live behind a single proxy (like corporate NAT), but it offers some protection against attacks coming from a single source IP.</p>
<p>The software is released under the Apache 2.0 Open Source License.</p>
<p>From the docs:</p>
<p>mod_memcache_block is an Apache module that allows you to block access to your servers using a block list stored in memcache. It also offers distributed rate limiting based on HTTP response code.</p>
<p><strong>FEATURES</strong></p>
<p>Distributed White and Black listing of IPs, ranges, and CIDR blocks<br />
Configurable timeouts, memcache server listings<br />
Support for continuous hasing using libmemcached’s Ketama<br />
Windowded Rate limiting based on Response code (to block brute-force dictionary attacks against .htpasswd, for example)</p>
<p><strong>REQUIREMENTS</strong></p>
<p>libmemcached-0.25 or better<br />
Memcached server<br />
Apache 2.x (tested with 2.2.11)</p>
<p><em>Source code is available here:</em><br />
<a href="http://github.com/netik/mod_memcache_block">http://github.com/netik/mod_memcache_block</a></p>
<p>If you would like to work on mod_memcache_block, contact me with your GitHub username and I&#8217;ll give you commit access on github.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/announcing-mod_memcache_block.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Twitter in New York magazine</title>
		<link>http://www.retina.net/tech/twitter-in-new-york-magazine.html</link>
		<comments>http://www.retina.net/tech/twitter-in-new-york-magazine.html#comments</comments>
		<pubDate>Mon, 09 Feb 2009 22:30:55 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[stuff]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=199</guid>
		<description><![CDATA[



Image by davidwatts1978 via Flickr



Normally I don&#8217;t re-post Twitter articles here but this one on the New York magazine was wistful, fair, balanced, and gave a good representation of what it&#8217;s like to work here. 
The reporter was in the office on the very day the US Airways flight crashed into the Hudson, and he [...]]]></description>
			<content:encoded><![CDATA[<div class="zemanta-img" style="margin: 1em; padding: 2em; display: block;">
<div>
<dl style="width: 190px;" class="wp-caption alignright">
<dt class="wp-caption-dt"><a href="http://www.flickr.com/photos/8188932@N02/3199405401"><img src="http://farm4.static.flickr.com/3493/3199405401_40c5b5b79f_m.jpg" alt="US Airways Flight 1549 Plane Crash Hudson in N..." title="US Airways Flight 1549 Plane Crash Hudson in N..." height="240" width="180"></a></dt>
<dd class="wp-caption-dd zemanta-img-attribution" style="font-size: 0.8em;">Image by <a href="http://www.flickr.com/photos/8188932@N02/3199405401">davidwatts1978</a> via Flickr</dd>
</dl>
</div>
</div>
<p>Normally I don&#8217;t re-post Twitter articles here but this one on the New York magazine was wistful, fair, balanced, and gave a good representation of what it&#8217;s like to work here. </p>
<p>The reporter was in the office on the very day the US Airways flight crashed into the Hudson, and he recorded our (completely boring) reactions to the event.</p>
<p><i><br />
Sure, the Twitter guys still have no idea how to make money off their fabulous invention. But for now they are living in a dreamworld of infinite possibilities, maybe the last one on Earth.<br />
</i></p>
<p><a href="http://nymag.com/news/media/54069/">How Tweet it Is &#8211; New York Magazine</a></p>
<div style="margin-top: 10px; height: 15px;" class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/2d3fdeba-aafc-46ed-9fde-38fd183e1bbd/" title="Zemified by Zemanta"><img style="border: medium none ; float: right;" class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_e.png?x-id=2d3fdeba-aafc-46ed-9fde-38fd183e1bbd" alt="Reblog this post [with Zemanta]"></a></div>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/twitter-in-new-york-magazine.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improving Javascript Load Times using Google AJAX API</title>
		<link>http://www.retina.net/tech/improving-javascript-load-times-using-google-ajax-api.html</link>
		<comments>http://www.retina.net/tech/improving-javascript-load-times-using-google-ajax-api.html#comments</comments>
		<pubDate>Mon, 22 Sep 2008 20:12:26 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[peformance]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[web development]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[pageload]]></category>
		<category><![CDATA[performance]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=123</guid>
		<description><![CDATA[If your site uses common AJAX libraries like jQuery, jQuery UI, mootools, prototype, script.aculo.us, or dojo, the first thing that you&#8217;ll notice is that these libraries are quite large and impact page load time.
For a browser with a completely empty cache, the browser will load the requested library (and block all other requests during the [...]]]></description>
			<content:encoded><![CDATA[<p>If your site uses common AJAX libraries like jQuery, jQuery UI, mootools, prototype, script.aculo.us, or dojo, the first thing that you&#8217;ll notice is that these libraries are quite large and impact page load time.</p>
<p>For a browser with a completely empty cache, the browser will load the requested library (and block all other requests during the load). For every site the user visits, the library is loaded again and again because the cache does not work across sites. Loading site1.com/jquery.js and site2.com/jquery.js takes the same amount of time.</p>
<p>Google&#8217;s come up with a clever solution to this problem. Instead of pointing to your local copy of whatever AJAX library you want, you point to Google&#8217;s copy using their <a href="http://code.google.com/apis/ajaxlibs/documentation/index.html#script_aculo_us">AJAX Libraries API</a>.</p>
<p>There&#8217;s many advantages to this. If the user has been to Gmail or any Google property recently, the library is already loaded in their browser, ready to execute. If the user goes to other sites which use the API, their cache is already primed and does not need to be loaded again. </p>
<p>We&#8217;ve just put this in place over at <a href="http://www.twitter.com">Twitter</a>, and it should improve page load times dramatically.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/improving-javascript-load-times-using-google-ajax-api.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Automated Face Replacement</title>
		<link>http://www.retina.net/tech/automated-face-replacement.html</link>
		<comments>http://www.retina.net/tech/automated-face-replacement.html#comments</comments>
		<pubDate>Mon, 18 Aug 2008 07:07:06 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[photography]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[Columbia University]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=112</guid>
		<description><![CDATA[As someone who takes many photographs of random people in nightclubs and at events, I&#8217;m intrigued by the efforts of Columbia University&#8217;s team to write software that performs automated face replacement in digital photographs.
The software is able to replace faces within images from a database of candidate images drawn from the Internet and other sources, [...]]]></description>
			<content:encoded><![CDATA[<p>As someone who takes many photographs of random people in nightclubs and at events, I&#8217;m intrigued by the efforts of Columbia University&#8217;s team to write software that performs automated face replacement in digital photographs.</p>
<p>The software is able to replace faces within images from a database of candidate images drawn from the Internet and other sources, and does so automatically.</p>
<p><a href="http://www1.cs.columbia.edu/CAVE/projects/face_replace/video/SIGGRAPH2008.wmv">A movie of their efforts exists here&#8230;</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/automated-face-replacement.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>ack!</title>
		<link>http://www.retina.net/tech/ack.html</link>
		<comments>http://www.retina.net/tech/ack.html#comments</comments>
		<pubDate>Thu, 17 Jul 2008 07:43:33 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[peformance]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[systems administration]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=71</guid>
		<description><![CDATA[I&#8217;ve been experimenting with a few things this week while trying to wade my way through Twitter&#8217;s infrastructure. One tool that&#8217;s been of extreme help in digging through source code and an extensive set of configuration files has been ack!
It&#8217;s the only piece of software I know of that has &#8216;&#8211;thpppt&#8217; as an option (Install [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been experimenting with a few things this week while trying to wade my way through <a href="http://www.twitter.com">Twitter&#8217;s</a> infrastructure. One tool that&#8217;s been of extreme help in digging through source code and an extensive set of configuration files has been <a href="http://petdance.com/ack/">ack!</a></p>
<p>It&#8217;s the only piece of software I know of that has &#8216;&#8211;thpppt&#8217; as an option (Install it, and you&#8217;ll see.) It&#8217;s an optimized replacement for many of your favorite awk | grep | sed combinations, and includes syntax highlighting. </p>
<p>In other news, I&#8217;ve resolved a number of bugs and issued new code for running <a href="http://code.google.com/p/modtelemetry">mod_telemetry</a> on 64-bit Linux. Check out the SVN trunk for the latest branch. The data that this module has been providing to me has been invaluable for researching slow points in the back end.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/ack.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CommunityOne</title>
		<link>http://www.retina.net/tech/communityone.html</link>
		<comments>http://www.retina.net/tech/communityone.html#comments</comments>
		<pubDate>Sat, 12 Apr 2008 02:51:34 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[conferences]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[systems administration]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/?p=47</guid>
		<description><![CDATA[Sun Microsystems is hosting CommunityOne, a free tech conference at The Moscone Center, San Francisco. If you&#8217;d like to go for free, please register at http://developers.sun.com/events/communityone and use registration ID number W1082146 !
It&#8217;s on May 5th, 2008, only three weeks away!
Some info, follows, courtesy of the Sun site:
Join experts and contributors from dozens of free [...]]]></description>
			<content:encoded><![CDATA[<p>Sun Microsystems is hosting CommunityOne, a free tech conference at The Moscone Center, San Francisco. If you&#8217;d like to go for free, please register at http://developers.sun.com/events/communityone and use registration ID number W1082146 !</p>
<p>It&#8217;s on May 5th, 2008, only three weeks away!</p>
<p>Some info, follows, courtesy of the Sun site:</p>
<p>Join experts and contributors from dozens of free and open source projects driving innovation today. Gain skills and find solutions to advance your infrastructure, develop next-generation applications, and create compelling web experiences. Choose from 70+ sessions led by experts from 30+ communities on OSes, databases, web and app servers, scripting, Web 2.0, and more</p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/communityone.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Autocomplete in rails 2.0</title>
		<link>http://www.retina.net/tech/autocomplete-in-rails-20.html</link>
		<comments>http://www.retina.net/tech/autocomplete-in-rails-20.html#comments</comments>
		<pubDate>Thu, 20 Mar 2008 09:08:23 +0000</pubDate>
		<dc:creator>John Adams</dc:creator>
				<category><![CDATA[ruby on rails]]></category>
		<category><![CDATA[rubyrails]]></category>
		<category><![CDATA[software engineering]]></category>

		<guid isPermaLink="false">http://www.retina.net/tech/autocomplete-in-rails-20.html</guid>
		<description><![CDATA[There&#8217;s been some changes in the way that Rails 2.0 processes forms and form interaction with Ajax. Here&#8217;s a quick write-up on how to use auto completion in Rails 2.0 without a database connection.
In my case, I was parsing an Apache configuration file and displaying VirtualHost entries, but you can use this for just about anything [...]]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s been some changes in the way that Rails 2.0 processes forms and form interaction with Ajax. Here&#8217;s a quick write-up on how to use auto completion in Rails 2.0 without a database connection.</p>
<p>In my case, I was parsing an Apache configuration file and displaying VirtualHost entries, but you can use this for just about anything (of course, models work too if you&#8217;d like to go against the DB)</p>
<p>First, install the auto complete plugin. Rails 2.0 doesn&#8217;t have autocomplete in the core anymore, so you&#8217;ll have to create your project with the usual <strong>rails myproject</strong> syntax, and then enter that directory with <strong>cd myproject</strong>.</p>
<p>Type &#8220;script/plugin install auto_complete&#8221; to install the auto complete plugin.</p>
<p>Next, we create a simple class to hold our data. You could parse a file here (say, with File.open()), or pull data from other sources in the initialize function of this class. If you&#8217;ve got a model in the database, you can use that.</p>
<p>class Apacheconf</p>
<p>@names = []</p>
<p>def names<br />
@names<br />
end</p>
<p>def initialize<br />
# replace this code later with parsing code</p>
<p>@names = Array.new<br />
@names &lt;&lt; &#8220;alpha&#8221;<br />
@names &lt;&lt; &#8220;beta&#8221;<br />
@names &lt;&lt; &#8220;gamma&#8221;<br />
@names &lt;&lt; &#8220;delta&#8221;<br />
end</p>
<p>end</p>
<p>&#8230; then we add some code and CSS to our view for the affiliate/index method in app/views/affiliate/index.rhtml</p>
<p>&lt;html&gt;</p>
<p>&lt;head&gt;</p>
<p>&lt;%= javascript_include_tag :defaults %&gt;</p>
<p>&lt;style&gt;</p>
<p>div.auto_complete {<br />
  width: 300px; <br />
  background: #fff; <br />
} </p>
<p>div.auto_complete ul { <br />
  border: 1px solid #888; <br />
  margin: 0px; <br />
  padding: 0px; <br />
  width: 100%; <br />
  list-style-type: none; <br />
} </p>
<p>div.auto_complete ul li { <br />
  margin: 0px; <br />
  padding: 3px; <br />
} </p>
<p>div.auto_complete ul li.selected { <br />
  background-color: #ffb; <br />
} </p>
<p>div.auto_complete ul strong.highlight { <br />
  color: #800; <br />
  margin: 0px; <br />
  padding: 0px; <br />
} </p>
<p>&lt;/style&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;% form_tag :action =&gt; &#8220;edit&#8221; do %&gt;<br />
&lt;p&gt;&lt;%= text_field &#8216;affiliate&#8217;, &#8216;name&#8217;, :autocomplete =&gt; &#8216;off&#8217; %&gt;&lt;/p&gt;<br />
&lt;div class=&#8221;auto_complete&#8221; id=&#8221;affiliate_name_auto_complete&#8221;&gt;&lt;/div&gt; <br />
&lt;%= auto_complete_field :affiliate_name,<br />
     :url =&gt; { :action=&gt;&#8217;autocomplete_affiliate_name&#8217; },<br />
     :tokens =&gt; &#8216;,&#8217; %&gt;<br />
    &lt;%= submit_tag %&gt;<br />
    &lt;% end %&gt;<br />
&lt;/body&gt;</p>
<p>&#8230; and then we insert a very small amount of code into the controler (in app/controllers/affiliate_controler.rb)  to handle the Ajax callback:</p>
<p>class AffiliateController &lt; ApplicationController<br />
  skip_before_filter :verify_authenticity_token, <img src='http://www.retina.net/tech/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> nly =&gt; [:autocomplete_affiliate_name]  </p>
<p>  def autocomplete_affiliate_name<br />
     # this code is called over and over again by Ajax<br />
     #<br />
     # the next line does a search through the array for terms starting with the <br />
     # specified parameters.</p>
<p>     @x = Apacheconf.new.names<br />
     @affiliates = @x.select { |v| v =~ /^#{params[:affiliate][:name]}/ }</p>
<p>     # don&#8217;t render the layout &#8211; we only want the partial to be rendered<br />
     render :layout=&gt;false <br />
  end</p>
<p>end</p>
<p> </p>
<p>The beauty of this that with the plugin installed, it takes very little work to get autocomplete working.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.retina.net/tech/autocomplete-in-rails-20.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
	</channel>
</rss>
