<?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:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Jim Neath - Ruby and Rails and Facebook Developer</title>
    <link>http://jimneath.org</link>
    <language>en</language>
    <webMaster>jimneath@gmail.com (Jim Neath)</webMaster>
    <pubDate>2012-02-07T13:51:29+00:00</pubDate>
    <copyright>Copyright 2008-2011</copyright>
    <ttl>60</ttl>
    <description>Ruby on Rails, Javascript, Facebook and Twitter app development</description>
    
    <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/JimNeath" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="jimneath" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
      <title>Ruby SSL Certificate Verify Failed</title>
      <link>http://jimneath.org/2011/10/19/ruby-ssl-certificate-verify-failed.html.html</link>
      <pubDate>Wed Oct 19 13:37:32 +0100 2011</pubDate>
      <guid>http://jimneath.org/2011/10/19/ruby-ssl-certificate-verify-failed.html</guid>
      <description>&lt;p&gt;If you&amp;#8217;re using Ruby to open connections to an external server over https, eg. the Facebook Graph API, you may run into the following error:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;SSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;SSLError&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='no'&gt;SSL_connect&lt;/span&gt; &lt;span class='n'&gt;returned&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt; &lt;span class='n'&gt;errno&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt; &lt;span class='n'&gt;state&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='no'&gt;SSLv3&lt;/span&gt; &lt;span class='n'&gt;read&lt;/span&gt; &lt;span class='n'&gt;server&lt;/span&gt; &lt;span class='n'&gt;certificate&lt;/span&gt; &lt;span class='n'&gt;B&lt;/span&gt;&lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='n'&gt;certificate&lt;/span&gt; &lt;span class='n'&gt;verify&lt;/span&gt; &lt;span class='n'&gt;failed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This error is due to Ruby not being able to find the certification authority certificates (CA Certs) used to verify the authenticity of secured web servers. The solution is to download the this &lt;a href='http://curl.haxx.se/ca/ca-bundle.crt'&gt;ca-bundle.crt&lt;/a&gt; into your application&amp;#8217;s &lt;code&gt;lib/&lt;/code&gt; directory:&lt;/p&gt;

&lt;p&gt;Then add the following code to &lt;code&gt;config/initializers/fix_ssl.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;open-uri&amp;#39;&lt;/span&gt;
&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;net/https&amp;#39;&lt;/span&gt;

&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Net&lt;/span&gt;
  &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;HTTP&lt;/span&gt;
    &lt;span class='n'&gt;alias_method&lt;/span&gt; &lt;span class='ss'&gt;:original_use_ssl&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:use_ssl&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;
    
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;use_ssl&lt;/span&gt;&lt;span class='o'&gt;=&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;flag&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;ca_file&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Rails&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;root&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;join&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;lib/ca-bundle.crt&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;verify_mode&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;OpenSSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;SSL&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;VERIFY_PEER&lt;/span&gt;
      &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;original_use_ssl&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;flag&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This should force ruby to use the CA bundle from your application&amp;#8217;s &lt;code&gt;lib/&lt;/code&gt; directory.&lt;/p&gt;

&lt;p&gt;Party on, Wayne!&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Serving Your Facebook App's Maintenance Page for POST Requests</title>
      <link>http://jimneath.org/2011/04/05/serving-your-facebook-apps-maintenance-page-for-post-requests.html.html</link>
      <pubDate>Tue Apr 05 13:37:32 +0100 2011</pubDate>
      <guid>http://jimneath.org/2011/04/05/serving-your-facebook-apps-maintenance-page-for-post-requests.html</guid>
      <description>&lt;p&gt;The standard way of deploying rails applications is to serve a static maintenance page while the code is being updated, to prevent errors being thrown by the user and to prevent writes happening to your database. This is all fine and dandy in the real world but in &lt;a href='http://www.facebook.com'&gt;Facebook&lt;/a&gt; land we run into issues.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Facebook will always send a POST on the initial iframe request for security reasons, and this can be to any end-point in our application, while in reality, this should be treated as a GET.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, the first time a page of your app is requested by user, Facebook sends a &lt;code&gt;POST&lt;/code&gt; request. If you&amp;#8217;re currently in maintenance mode you&amp;#8217;re going to get a big &lt;a href='http://www.checkupdown.com/status/E405.html'&gt;&lt;code&gt;405 Method not allowed&lt;/code&gt;&lt;/a&gt; error.&lt;/p&gt;

&lt;p&gt;To fix this we need to tell &lt;a href='http://wiki.nginx.org/'&gt;nginx&lt;/a&gt; to serve your maintenance page to &lt;code&gt;POST&lt;/code&gt; requests, as well as &lt;code&gt;GET&lt;/code&gt; requests. We can do this by updating your servers config files. Say your &lt;code&gt;server&lt;/code&gt; config initially looks like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;server &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='c'&gt;# all your other server stuff&lt;/span&gt;
  &lt;span class='c'&gt;# ...&lt;/span&gt;

  &lt;span class='c'&gt;# show maintenance page if exists &lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;-f &lt;span class='nv'&gt;$document_root&lt;/span&gt;/system/maintenance.html&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    rewrite ^&lt;span class='o'&gt;(&lt;/span&gt;.*&lt;span class='o'&gt;)&lt;/span&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;/system/maintenance.html &lt;span class='nb'&gt;break&lt;/span&gt;;
    &lt;span class='nb'&gt;break&lt;/span&gt;;
  &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Add the following &lt;code&gt;location&lt;/code&gt; rule to allow nginx to serve the page for &lt;code&gt;POST&lt;/code&gt; requests:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;server &lt;span class='o'&gt;{&lt;/span&gt;
  &lt;span class='c'&gt;# all your other server stuff&lt;/span&gt;
  &lt;span class='c'&gt;# ...&lt;/span&gt;

  &lt;span class='c'&gt;# show maintenance page if exists &lt;/span&gt;
  &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;(&lt;/span&gt;-f &lt;span class='nv'&gt;$document_root&lt;/span&gt;/system/maintenance.html&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='o'&gt;{&lt;/span&gt;
    rewrite ^&lt;span class='o'&gt;(&lt;/span&gt;.*&lt;span class='o'&gt;)&lt;/span&gt;&lt;span class='nv'&gt;$ &lt;/span&gt;/system/maintenance.html &lt;span class='nb'&gt;break&lt;/span&gt;;
    &lt;span class='nb'&gt;break&lt;/span&gt;;
  &lt;span class='o'&gt;}&lt;/span&gt;

  &lt;span class='c'&gt;# serve maintenance page to POST requests&lt;/span&gt;
  &lt;span class='nv'&gt;location&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; /system/maintenance.html &lt;span class='o'&gt;{&lt;/span&gt;
    post_to_static on;
  &lt;span class='o'&gt;}&lt;/span&gt;
&lt;span class='o'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Reload your nginx config and everything should be rocking as expected.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Rails 3, nginx and send_file</title>
      <link>http://jimneath.org/2011/04/05/rails-3-nginx-and-send_file.html.html</link>
      <pubDate>Tue Apr 05 13:37:32 +0100 2011</pubDate>
      <guid>http://jimneath.org/2011/04/05/rails-3-nginx-and-send_file.html</guid>
      <description>&lt;p&gt;Trying to use &lt;code&gt;send_file&lt;/code&gt; from your Rails 3 app and getting a file with a size of zero bytes? It&amp;#8217;s more than likely that you&amp;#8217;re using nginx and haven&amp;#8217;t setup your app to use &lt;code&gt;send_file&lt;/code&gt; properly.&lt;/p&gt;

&lt;p&gt;Open up your &lt;code&gt;config/environments/production.rb&lt;/code&gt; file and find the following lines:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# Specifies the header that your server uses for sending files&lt;/span&gt;
&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;action_dispatch&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;x_sendfile_header&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;X-Sendfile&amp;quot;&lt;/span&gt;

&lt;span class='c1'&gt;# For nginx:&lt;/span&gt;
&lt;span class='c1'&gt;# config.action_dispatch.x_sendfile_header = &amp;#39;X-Accel-Redirect&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then comment out the first &lt;code&gt;config.action_dispatch.x_sendfile_header&lt;/code&gt; line and uncomment out the second. So it should look like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# Specifies the header that your server uses for sending files&lt;/span&gt;
&lt;span class='c1'&gt;# config.action_dispatch.x_sendfile_header = &amp;quot;X-Sendfile&amp;quot;&lt;/span&gt;

&lt;span class='c1'&gt;# For nginx:&lt;/span&gt;
&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;action_dispatch&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;x_sendfile_header&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;X-Accel-Redirect&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then just commit, push, deploy and &lt;em&gt;voila!&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Using Redis with Ruby on Rails</title>
      <link>http://jimneath.org/2011/03/24/using-redis-with-ruby-on-rails.html.html</link>
      <pubDate>Thu Mar 24 15:37:32 +0000 2011</pubDate>
      <guid>http://jimneath.org/2011/03/24/using-redis-with-ruby-on-rails.html</guid>
      <description>&lt;div class='buy'&gt;
  &lt;a href='http://www.amazon.com/gp/product/1449396097?tag=jimnearaidev-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1449396097'&gt;
    &lt;img alt='Redis Book' src='/images/posts/2011/redis-book.jpg' /&gt;
  &lt;/a&gt;
  &lt;h3&gt;&lt;a href='http://www.amazon.com/gp/product/1449396097?tag=jimnearaidev-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1449396097'&gt;Buy The Redis Book!&lt;/a&gt;&lt;/h3&gt;
  &lt;p&gt;Written by Redis creator, Salvatore Sanfilippo, and key contributor, Pieter Noordhuis, the Redis Book will show you how to work with different data structures, how to handle memory, replication, and the cache itself, and how to implement messaging, amongst other things! &lt;a href='http://www.amazon.com/gp/product/1449396097?tag=jimnearaidev-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1449396097'&gt;Buy the book&lt;/a&gt;&lt;/p&gt;
  &lt;img alt='' border='0' src='http://www.assoc-amazon.com/e/ir?t=jimnearaidev-20&amp;l=as2&amp;o=1&amp;a=1449396097&amp;camp=217145&amp;creative=399373' width='1' height='1' style='border:none !important; margin:0px !important;' /&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://redis.io'&gt;Redis&lt;/a&gt; is an extremely fast, atomic key-value store. It allows the storage of strings, sets, sorted sets, lists and hashes. Redis keeps all the data in RAM, much like &lt;a href='http://memcached.org/'&gt;Memcached&lt;/a&gt; but unlike Memcached, Redis periodically writes to disk, giving it persistence.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Redis is an open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.&lt;/p&gt;

&lt;p&gt;You can run atomic operations on these types, like appending to a string; incrementing the value in a hash; pushing to a list; computing set intersection, union and difference; or getting the member with highest ranking in a sorted set.&lt;/p&gt;

&lt;p&gt;In order to achieve its outstanding performance, Redis works with an in-memory dataset. Depending on your use case, you can persist it either by dumping the dataset to disk every once in a while, or by appending each command to a log.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The above quote was taken from the official &lt;a href='http://redis.io/topics/introduction'&gt;Introduction to Redis&lt;/a&gt; page.&lt;/p&gt;

&lt;h3 id='table_of_contents'&gt;Table of Contents&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='#redis_data_types'&gt;Redis Data Types&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#installing_redis'&gt;Installing Redis&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#starting_redis_server'&gt;Starting Redis Server&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#redis_and_rails'&gt;Redis and Rails&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#example_uses_in_rails'&gt;Example Uses in Rails&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#using_redis_as_your_rails_cache_store'&gt;Using Redis As Your Rails Cache Store&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#monitoring_redis'&gt;Monitoring Redis&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#redis_and_unix_sockets'&gt;Redis and Unix Sockets&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='#redis_related_gems'&gt;Redis Related Gems&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='redis_data_types'&gt;Redis Data Types&lt;/h3&gt;

&lt;p&gt;Below is a general overview of the data types available to you in Redis:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Data Type&lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands#string'&gt;String&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;A string of characters. The most basic data type. Can also be used as a counter, using &lt;code&gt;incr&lt;/code&gt;, &lt;code&gt;incrby&lt;/code&gt;, &lt;code&gt;decr&lt;/code&gt; and &lt;code&gt;decrby&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands#set'&gt;Set&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Sets are unsorted collections of strings with no duplicate members.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands#sorted_set'&gt;Sorted Set&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Sorted sets (&lt;code&gt;zset&lt;/code&gt;) are like sets in that each member has to be unqiue. Unlike sets, sorted sets have a score associated with each member&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands#list'&gt;List&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Lists are sorted collections of strings, essentially like an &lt;code&gt;Array&lt;/code&gt; in ruby. You can &lt;code&gt;push&lt;/code&gt; and &lt;code&gt;pop&lt;/code&gt; on either end, making them useful for queues.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands#hash'&gt;Hash&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Hashes are what you&amp;#8217;d expect: keys and string values.&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;As well as those basic types, there is also the ability to do &lt;a href='http://redis.io/commands#pubsub'&gt;PubSub&lt;/a&gt; with Redis. A &lt;a href='http://redis.io/commands'&gt;full list of Redis commands&lt;/a&gt; is available on the official site.&lt;/p&gt;

&lt;h3 id='installing_redis'&gt;Installing Redis&lt;/h3&gt;

&lt;p&gt;Installation is simple:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;curl -O http://redis.googlecode.com/files/redis-2.2.2.tar.gz
tar xzf redis-2.2.2.tar.gz
&lt;span class='nb'&gt;cd &lt;/span&gt;redis-2.2.2
make
cp src/redis-server src/redis-cli /usr/bin
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='starting_redis_server'&gt;Starting Redis Server&lt;/h3&gt;

&lt;p&gt;If you&amp;#8217;re using &lt;code&gt;redis-server&lt;/code&gt; locally, you can get away with just running the following, which will use the default Redis config file:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;redis-server
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;#8217;re running it on a server you&amp;#8217;ll probably want to use your own config file:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;redis-server /path/to/redis.conf
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The default redis.conf looks like &lt;a href='https://github.com/antirez/redis/blob/master/redis.conf'&gt;this&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id='redis_and_rails'&gt;Redis and Rails&lt;/h3&gt;

&lt;p&gt;Now that we have Redis installed and running, we need to get it playing nice with Rails. Enter redis-rb, created by &lt;a href='http://brainspl.at/'&gt;Ezra Zygmuntowicz&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/ezmobius/redis-rb' class='github'&gt;https://github.com/ezmobius/redis-rb&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First step, add redis-rb to your &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;redis&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;2.1.1&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then install the gem via Bundler:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Lastly, create an initializer in &lt;code&gt;config/initializers/redis.rb&lt;/code&gt; and add the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='vg'&gt;$redis&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:host&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;localhost&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:port&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;6379&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This will create a new instance of the Redis client, connected to &lt;code&gt;localhost:6379&lt;/code&gt; (the default), and store it in the global variable &lt;code&gt;$redis&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;#8217;s check that everything is working by firing up &lt;code&gt;rails console&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='vg'&gt;$redis&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='c1'&gt;#&amp;lt;Redis client v2.1.1 connected to redis://localhost:6379/0 (Redis v2.2.2)&amp;gt; &lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;set&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;chunky&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;bacon&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;OK&amp;quot;&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;chunky&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;bacon&amp;quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='example_uses_in_rails'&gt;Example Uses in Rails&lt;/h3&gt;

&lt;h4 id='user_friendships'&gt;User Friendships&lt;/h4&gt;

&lt;p&gt;The first example I&amp;#8217;ll show you is modelling friendships using &lt;code&gt;ActiveRecord&lt;/code&gt; and Redis. We&amp;#8217;ll be using &lt;a href='http://redis.io/commands#set'&gt;sets&lt;/a&gt; to store the friendship data. Here is our &lt;code&gt;User&lt;/code&gt; model:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
  &lt;span class='c1'&gt;# follow a user&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;follow!&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;multi&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sadd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:following&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sadd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:followers&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# unfollow a user&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;unfollow!&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;multi&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt;
      &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;srem&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:following&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;srem&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:followers&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# users that self follows&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;followers&lt;/span&gt;
    &lt;span class='n'&gt;user_ids&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;smembers&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:followers&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;where&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;user_ids&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='c1'&gt;# users that follow self&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;following&lt;/span&gt;
    &lt;span class='n'&gt;user_ids&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;smembers&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:following&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;where&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;user_ids&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='c1'&gt;# users who follow and are being followed by self&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;friends&lt;/span&gt;
    &lt;span class='n'&gt;user_ids&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sinter&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:following&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:followers&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
    &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;where&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:id&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;user_ids&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='c1'&gt;# does the user follow self&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;followed_by?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sismember&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:followers&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# does self follow user&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;following?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;sismember&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:following&lt;/span&gt;&lt;span class='p'&gt;),&lt;/span&gt; &lt;span class='n'&gt;user&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='c1'&gt;# number of followers&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;followers_count&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scard&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:followers&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;

  &lt;span class='c1'&gt;# number of users being followed&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;following_count&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scard&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:following&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# helper method to generate redis keys&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;redis_key&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;str&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='s2'&gt;&amp;quot;user:&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;:&lt;/span&gt;&lt;span class='si'&gt;#{&lt;/span&gt;&lt;span class='n'&gt;str&lt;/span&gt;&lt;span class='si'&gt;}&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Some sample useage:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='sx'&gt;%w[Alfred Bob]&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;create&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:name&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='nb'&gt;name&lt;/span&gt;&lt;span class='p'&gt;)}&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Alfred&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Bob&amp;#39;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;all&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 1, name: &amp;quot;Alfred&amp;quot;&amp;gt;, #&amp;lt;User id: 2, name: &amp;quot;Bob&amp;quot;&amp;gt;] &lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;follow!&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;following?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;followed_by?&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;following&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 2, name: &amp;quot;Bob&amp;quot;&amp;gt;] &lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;followers&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 1, name: &amp;quot;Alfred&amp;quot;&amp;gt;]&lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;friends&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[]&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;follow!&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;friends&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 2, name: &amp;quot;Bob&amp;quot;&amp;gt;] &lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;friends&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 1, name: &amp;quot;Alfred&amp;quot;&amp;gt;] &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It is all pretty simple. We&amp;#8217;re using the following set commands: &lt;code&gt;sadd&lt;/code&gt;, &lt;code&gt;srem&lt;/code&gt;, &lt;code&gt;smembers&lt;/code&gt;, &lt;code&gt;sinter&lt;/code&gt;, &lt;code&gt;scard&lt;/code&gt;, &lt;code&gt;sismember&lt;/code&gt; and the &lt;code&gt;multi&lt;/code&gt; command. An overview of the commands is provided below:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Command&lt;/th&gt;&lt;th&gt;Overview&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/sadd'&gt;sadd&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Add member to the set stored at key. If member is already a member of this set, no operation is performed. If key does not exist, a new set is created with member as its sole member.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/srem'&gt;srem&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Remove member from the set stored at key. If member is not a member of this set, no operation is performed.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/smembers'&gt;smembers&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns all the members of the set value stored at key.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/sinter'&gt;sinter&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns the members of the set resulting from the intersection of all the given sets.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/scard'&gt;scard&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns the set cardinality (number of elements) of the set stored at key.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/sismember'&gt;sismember&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns if member is a member of the set stored at key.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/multi'&gt;multi&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Marks the start of a transaction block. Subsequent commands will be queued for atomic execution using EXEC.&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 id='high_score_table'&gt;High Score Table&lt;/h4&gt;

&lt;p&gt;We can construct a simple high score table using Redis &lt;a href='http://redis.io/commands#sorted_set'&gt;sorted sets&lt;/a&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;User&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
  &lt;span class='c1'&gt;# log high score&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;scored&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;score&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;high_score&lt;/span&gt;
      &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;zadd&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;highscores&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;score&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# table rank&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;rank&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;zrevrank&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;highscores&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# high score&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;high_score&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;zscore&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;highscores&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_i&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
  
  &lt;span class='c1'&gt;# load top 3 users&lt;/span&gt;
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nc'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='nf'&gt;top_3&lt;/span&gt;
    &lt;span class='vg'&gt;$redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;zrevrange&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;highscores&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='mi'&gt;2&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;map&lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;find&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;id&lt;/span&gt;&lt;span class='p'&gt;)}&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Sample useage:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;limit&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 1, name: &amp;quot;Alfred&amp;quot;&amp;gt;, #&amp;lt;User id: 2, name: &amp;quot;Bob&amp;quot;&amp;gt;, #&amp;lt;User id: 3, name: &amp;quot;Charlie&amp;quot;&amp;gt;, #&amp;lt;User id: 4, name: &amp;quot;Derek&amp;quot;&amp;quot;&amp;gt;] &lt;/span&gt;
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;a&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scored&lt;/span&gt; &lt;span class='mi'&gt;100&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;b&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scored&lt;/span&gt; &lt;span class='mi'&gt;500&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scored&lt;/span&gt; &lt;span class='mi'&gt;25&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scored&lt;/span&gt; &lt;span class='mi'&gt;10000&lt;/span&gt;
 &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;high_score&lt;/span&gt;
 &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;10000&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;rank&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;rank&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;scored&lt;/span&gt; &lt;span class='mi'&gt;5000000&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;false&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;high_score&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;5000000&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;c&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;rank&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt; 
&lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;User&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;top_3&lt;/span&gt;
&lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='c1'&gt;#&amp;lt;User id: 3, name: &amp;quot;Charlie&amp;quot;&amp;gt;, #&amp;lt;User id: 4, name: &amp;quot;Derek&amp;quot;&amp;gt;, #&amp;lt;User id: 2, name: &amp;quot;Bob&amp;quot;&amp;gt;] &lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;We&amp;#8217;re using the following set commands: &lt;code&gt;zadd&lt;/code&gt;, &lt;code&gt;zrevrank&lt;/code&gt;, &lt;code&gt;zrevrange&lt;/code&gt; and the &lt;code&gt;zscore&lt;/code&gt; commands. An overview of the commands is provided below:&lt;/p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Command&lt;/th&gt;&lt;th&gt;Overview&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/zadd'&gt;zadd&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Adds the member with the specified score to the sorted set stored at key. If member is already a member of the sorted set, the score is updated and the element reinserted at the right position to ensure the correct ordering. If key does not exist, a new sorted set with the specified member as sole member is created.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/zrevrank'&gt;zrevrank&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns the rank of member in the sorted set stored at key, with the scores ordered from high to low. The rank (or index) is 0-based, which means that the member with the highest score has rank 0.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/zrevrange'&gt;zrevrange&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns the specified range of elements in the sorted set stored at key. The elements are considered to be ordered from the highest to the lowest score. Descending lexicographical order is used for elements with equal score.&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td style='text-align: left;'&gt;&lt;a href='http://redis.io/commands/zscore'&gt;zscore&lt;/a&gt;&lt;/td&gt;&lt;td style='text-align: left;'&gt;Returns the score of member in the sorted set at key.&lt;/td&gt;
&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h4 id='more_redis_use_cases'&gt;More Redis Use Cases&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href='http://www.paperplanes.de/2010/2/16/a_collection_of_redis_use_cases.html'&gt;A Collection Of Redis Use Cases&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;&lt;a href='http://nosql.mypopescu.com/post/836086276/presentation-redis-persistence-power-or-redis-use'&gt;Presentation: Redis - Persistence Power or Redis Use Cases&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id='using_redis_as_your_rails_cache_store'&gt;Using Redis As Your Rails Cache Store&lt;/h3&gt;

&lt;p&gt;If you want to use Redis as your cache store, then look no further than &lt;a href='https://github.com/rtomayko/rack-cache'&gt;Redis Store&lt;/a&gt; by Luca Guidi. Redis Store provides namespaced Rack::Session, Rack::Cache, I18n and cache Redis stores for Ruby web frameworks. It allows you to use Redis as your Rails cache store, session store and integrates well with &lt;a href='https://github.com/rtomayko/rack-cache'&gt;Rack::Cache&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/jodosha/redis-store' class='github'&gt;https://github.com/jodosha/redis-store&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First, let&amp;#8217;s add redis-store to the &lt;code&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;gem&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;redis-store&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;1.0.0.beta4&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then install the gem via Bundler:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;bundle install
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then update your &lt;code&gt;config/environments/production.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;config&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;cache_store&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='ss'&gt;:redis_store&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then you&amp;#8217;re good to go. Your cache store should now be using Redis.&lt;/p&gt;

&lt;h3 id='monitoring_redis'&gt;Monitoring Redis&lt;/h3&gt;

&lt;p&gt;If you&amp;#8217;re using Redis on your server and you have &lt;code&gt;daemonize&lt;/code&gt; set to &lt;code&gt;yes&lt;/code&gt; in your &lt;code&gt;redis.conf&lt;/code&gt;, you need to monitor it. Below are an example &lt;a href='http://mmonit.com/monit/'&gt;Monit&lt;/a&gt; and &lt;a href='http://god.rubyforge.org/'&gt;God&lt;/a&gt; script:&lt;/p&gt;

&lt;h4 id='monit'&gt;Monit&lt;/h4&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;check process redis
  start &lt;span class='nv'&gt;program&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/usr/bin/redis-server /etc/redis/redis.conf&amp;quot;&lt;/span&gt;
  stop &lt;span class='nv'&gt;program&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/usr/bin/redis-cli -p 6379 shutdown&amp;quot;&lt;/span&gt;
  with pidfile /var/run/redis.pid
  group redis
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h4 id='god'&gt;God&lt;/h4&gt;

&lt;p&gt;Adapted from this &lt;a href='https://gist.github.com/415369'&gt;Gist&lt;/a&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;%w&lt;span class='o'&gt;{&lt;/span&gt;6379&lt;span class='o'&gt;}&lt;/span&gt;.each &lt;span class='k'&gt;do&lt;/span&gt; |port|
  God.watch &lt;span class='k'&gt;do&lt;/span&gt; |w| 
    w.name &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;redis&amp;quot;&lt;/span&gt; 
    w.interval &lt;span class='o'&gt;=&lt;/span&gt; 30.seconds 
  
    w.start &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/usr/bin/redis-server /etc/redis/redis.conf&amp;quot;&lt;/span&gt; 
    w.stop &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/usr/bin/redis-cli -p 6379 shutdown&amp;quot;&lt;/span&gt; 
    w.restart &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;#{w.stop} &amp;amp;&amp;amp; #{w.start}&amp;quot;&lt;/span&gt; 
  
    w.start_grace &lt;span class='o'&gt;=&lt;/span&gt; 10.seconds 
    w.restart_grace &lt;span class='o'&gt;=&lt;/span&gt; 10.seconds 
  
    w.start_if &lt;span class='k'&gt;do&lt;/span&gt; |start| 
      start.condition&lt;span class='o'&gt;(&lt;/span&gt;:process_running&lt;span class='o'&gt;)&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; |c| 
        c.interval &lt;span class='o'&gt;=&lt;/span&gt; 5.seconds 
        c.running &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;false &lt;/span&gt;
&lt;span class='nb'&gt;      &lt;/span&gt;end 
    end 
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='redis_and_unix_sockets'&gt;Redis and Unix Sockets&lt;/h3&gt;

&lt;p&gt;Redis 2.2 introduced the ability to connect to Redis via unix sockets. To allow this functionality you need to uncomment the following line in your &lt;code&gt;redis.conf&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;unixsocket /tmp/redis.sock
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then you can connect to Redis in your app, change the contents of your &lt;code&gt;config/initializers/redis.rb&lt;/code&gt;, to this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='vg'&gt;$redis&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Redis&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;new&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:path&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;/tmp/redis.sock&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Below are some rough benchmarks from my MacBook Pro:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;~ redis-benchmark -q
PING &lt;span class='o'&gt;(&lt;/span&gt;inline&lt;span class='o'&gt;)&lt;/span&gt;: 54347.82 requests per second
PING: 52083.33 requests per second
MSET &lt;span class='o'&gt;(&lt;/span&gt;10 keys&lt;span class='o'&gt;)&lt;/span&gt;: 28571.43 requests per second
SET: 48309.18 requests per second
GET: 49504.95 requests per second
INCR: 47846.89 requests per second
LPUSH: 48309.18 requests per second
LPOP: 49751.24 requests per second
SADD: 48543.69 requests per second
SPOP: 51282.05 requests per second
LPUSH &lt;span class='o'&gt;(&lt;/span&gt;again, in order to bench LRANGE&lt;span class='o'&gt;)&lt;/span&gt;: 48076.92 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 100 elements&lt;span class='o'&gt;)&lt;/span&gt;: 34129.69 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 300 elements&lt;span class='o'&gt;)&lt;/span&gt;: 17064.85 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 450 elements&lt;span class='o'&gt;)&lt;/span&gt;: 13661.20 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 600 elements&lt;span class='o'&gt;)&lt;/span&gt;: 11074.20 requests per second

~ redis-benchmark -q -s /tmp/redis.sock
PING &lt;span class='o'&gt;(&lt;/span&gt;inline&lt;span class='o'&gt;)&lt;/span&gt;: 80000.00 requests per second
PING: 82644.62 requests per second
MSET &lt;span class='o'&gt;(&lt;/span&gt;10 keys&lt;span class='o'&gt;)&lt;/span&gt;: 41841.00 requests per second
SET: 72463.77 requests per second
GET: 81300.81 requests per second
INCR: 63694.27 requests per second
LPUSH: 70422.53 requests per second
LPOP: 80000.00 requests per second
SADD: 72463.77 requests per second
SPOP: 77519.38 requests per second
LPUSH &lt;span class='o'&gt;(&lt;/span&gt;again, in order to bench LRANGE&lt;span class='o'&gt;)&lt;/span&gt;: 80645.16 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 100 elements&lt;span class='o'&gt;)&lt;/span&gt;: 42372.88 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 300 elements&lt;span class='o'&gt;)&lt;/span&gt;: 22779.04 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 450 elements&lt;span class='o'&gt;)&lt;/span&gt;: 16891.89 requests per second
LRANGE &lt;span class='o'&gt;(&lt;/span&gt;first 600 elements&lt;span class='o'&gt;)&lt;/span&gt;: 13458.95 requests per second
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;h3 id='redis_related_gems'&gt;Redis Related Gems&lt;/h3&gt;

&lt;h4 id='redis_objects'&gt;&lt;a href='https://github.com/nateware/redis-objects'&gt;Redis Objects&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Redis objects maps redis data types to ruby objects. Created as a compliment for current ORMs instead of a replacement.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/nateware/redis-objects' class='github'&gt;https://github.com/nateware/redis-objects&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='resque'&gt;&lt;a href='https://github.com/defunkt/resque'&gt;Resque&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Resque (pronounced like &amp;#8220;rescue&amp;#8221;) is a Redis-backed library for creating background jobs, placing those jobs on multiple queues, and processing them later. It was written by &lt;a href='http://github.com'&gt;GitHub&lt;/a&gt; and is used in production there, as well as on many other apps. Read their blog post: &lt;a href='https://github.com/blog/542-introducing-resque'&gt;Introducing Resque&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/defunkt/resque' class='github'&gt;https://github.com/defunkt/resque&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='vanity'&gt;&lt;a href='https://github.com/assaf/vanity'&gt;Vanity&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;a href='http://vanity.labnotes.org/'&gt;Vanity&lt;/a&gt; is an Experiment Driven Development framework for Rails that uses Redis. It allows you to define A/B tests in your Ruby on Rails application and integrates with Google Analytics via &lt;a href='https://github.com/vigetlabs/garb'&gt;Garb&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/assaf/vanity' class='github'&gt;https://github.com/assaf/vanity&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='ohm'&gt;&lt;a href='https://github.com/soveran/ohm'&gt;Ohm&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Ohm is a library for storing objects in Redis, a persistent key-value database. It includes an extensible list of validations and has very good performance.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/soveran/ohm' class='github'&gt;https://github.com/soveran/ohm&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='rollout'&gt;&lt;a href='https://github.com/jamesgolick/rollout'&gt;Rollout&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;Rollout lets you roll out new features to select groups of users for testing. Rollout has been covered on &lt;a href='http://thechangelog.com/post/859235082/rollout-conditionally-roll-out-features-with-redis'&gt;the changelog&lt;/a&gt;. Also works in tandem with &lt;a href='https://github.com/jamesgolick/degrade'&gt;Degrade&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/jamesgolick/rollout' class='github'&gt;https://github.com/jamesgolick/rollout&lt;/a&gt;&lt;/p&gt;

&lt;h4 id='soulmate'&gt;&lt;a href='https://github.com/seatgeek/soulmate'&gt;Soulmate&lt;/a&gt;&lt;/h4&gt;

&lt;p&gt;&lt;a href='http://seatgeek.com/blog/dev/announcing-soulmate-a-redis-backed-service-for-fast-autocompleting'&gt;Soulmate&lt;/a&gt; is a tool to help solve the common problem of developing a fast autocomplete feature. It uses Redis&amp;#8217;s sorted sets to build an index of partially completed words and the corresponding top matching items.&lt;/p&gt;

&lt;p&gt;&lt;a href='https://github.com/seatgeek/soulmate' class='github'&gt;https://github.com/seatgeek/soulmate&lt;/a&gt;&lt;/p&gt;
&lt;div class='buy'&gt;
  &lt;a href='http://www.amazon.com/gp/product/1449396097?tag=jimnearaidev-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1449396097'&gt;
    &lt;img alt='Redis Book' src='/images/posts/2011/redis-book.jpg' /&gt;
  &lt;/a&gt;
  &lt;h3&gt;&lt;a href='http://www.amazon.com/gp/product/1449396097?tag=jimnearaidev-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1449396097'&gt;Buy The Redis Book!&lt;/a&gt;&lt;/h3&gt;
  &lt;p&gt;Written by Redis creator, Salvatore Sanfilippo, and key contributor, Pieter Noordhuis, the Redis Book will show you how to work with different data structures, how to handle memory, replication, and the cache itself, and how to implement messaging, amongst other things! &lt;a href='http://www.amazon.com/gp/product/1449396097?tag=jimnearaidev-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399373&amp;creativeASIN=1449396097'&gt;Buy the book&lt;/a&gt;&lt;/p&gt;
  &lt;img alt='' border='0' src='http://www.assoc-amazon.com/e/ir?t=jimnearaidev-20&amp;l=as2&amp;o=1&amp;a=1449396097&amp;camp=217145&amp;creative=399373' width='1' height='1' style='border:none !important; margin:0px !important;' /&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Showing Passenger Stats From Inside Your App</title>
      <link>http://jimneath.org/2011/03/23/showing-passenger-stats-inside-your-app.html.html</link>
      <pubDate>Wed Mar 23 12:37:32 +0000 2011</pubDate>
      <guid>http://jimneath.org/2011/03/23/showing-passenger-stats-inside-your-app.html</guid>
      <description>&lt;p&gt;If you&amp;#8217;ve ever wanted to know how many active or idle &lt;a href='http://www.modrails.com/'&gt;Passenger&lt;/a&gt; processes your server has and display them inside your app, you can use the following helper:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;passenger_stats&lt;/span&gt;
  &lt;span class='vi'&gt;@passenger_stats&lt;/span&gt; &lt;span class='o'&gt;||=&lt;/span&gt; &lt;span class='k'&gt;begin&lt;/span&gt;
    &lt;span class='sb'&gt;`passenger-status`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;split&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='se'&gt;\n&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;inject&lt;/span&gt;&lt;span class='p'&gt;({})&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;memo&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt; 
      &lt;span class='n'&gt;memo&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;merge&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;[/^&lt;/span&gt;&lt;span class='p'&gt;\&lt;/span&gt;&lt;span class='n'&gt;w&lt;/span&gt;&lt;span class='o'&gt;+/].&lt;/span&gt;&lt;span class='n'&gt;to_sym&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;line&lt;/span&gt;&lt;span class='o'&gt;[/&lt;/span&gt;&lt;span class='p'&gt;\&lt;/span&gt;&lt;span class='n'&gt;d&lt;/span&gt;&lt;span class='o'&gt;+&lt;/span&gt;&lt;span class='vg'&gt;$/&lt;/span&gt;&lt;span class='o'&gt;].&lt;/span&gt;&lt;span class='n'&gt;to_i&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Calling &lt;code&gt;passenger_stats&lt;/code&gt; will return a hash resembling the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='ss'&gt;:inactive&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:count&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:max&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;15&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:active&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;3&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Which you could then display in your views, thus:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;span class='nt'&gt;&amp;lt;h3&amp;gt;&lt;/span&gt;Passenger Stats&lt;span class='nt'&gt;&amp;lt;/h3&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Total:&lt;span class='nt'&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class='err'&gt;&amp;lt;&lt;/span&gt;%= passenger_stats[:total] %&amp;gt;&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Maximum:&lt;span class='nt'&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class='err'&gt;&amp;lt;&lt;/span&gt;%= passenger_stats[:max] %&amp;gt;&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Active:&lt;span class='nt'&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class='err'&gt;&amp;lt;&lt;/span&gt;%= passenger_stats[:active] %&amp;gt;&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class='nt'&gt;&amp;lt;p&amp;gt;&amp;lt;strong&amp;gt;&lt;/span&gt;Inactive:&lt;span class='nt'&gt;&amp;lt;/strong&amp;gt;&lt;/span&gt; &lt;span class='err'&gt;&amp;lt;&lt;/span&gt;%= passenger_stats[:inactive] %&amp;gt;&lt;span class='nt'&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Enjoy.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Fixing NGINX 201 Content-Length Header Bug</title>
      <link>http://jimneath.org/2011/03/22/fixing-nginx-201-content-length-header-bug.html.html</link>
      <pubDate>Tue Mar 22 14:40:26 +0000 2011</pubDate>
      <guid>http://jimneath.org/2011/03/22/fixing-nginx-201-content-length-header-bug.html</guid>
      <description>&lt;p&gt;&lt;a href='http://nginx.org/'&gt;NGINX&lt;/a&gt; is an awesome server, but unfortunately contains an error in earlier versions (pre &lt;a href='http://nginx.org/en/CHANGES'&gt;0.8.32&lt;/a&gt;), that sends the incorrect headers for 201 (created) responses. It does not set the &lt;code&gt;Content-Length&lt;/code&gt; header, which causes modern browsers to keep the connection open and wait until the timeout value is exceeded.&lt;/p&gt;

&lt;p&gt;There are two possible fixes for this; Upgrade NGINX to version 0.8.32 or greater, or fix the issue in your server side code. I&amp;#8217;ll show you how we can do the latter, using &lt;a href='http://rack.rubyforge.org/'&gt;Rack&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Rack provides a minimal, modular and adaptable interface for developing web applications in Ruby. By wrapping HTTP requests and responses in the simplest way possible, it unifies and distills the API for web servers, web frameworks, and software in between (the so-called middleware) into a single method call.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will use a piece of Rack middleware to set the correct headers for any 201 responses.&lt;/p&gt;

&lt;p&gt;Copy the code below into &lt;code&gt;lib/content_length_fix.rb&lt;/code&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;module&lt;/span&gt; &lt;span class='nn'&gt;Nginx&lt;/span&gt;
  &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;ContentLengthFix&lt;/span&gt;
    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;initialize&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;app&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='vi'&gt;@app&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;app&lt;/span&gt;       
    &lt;span class='k'&gt;end&lt;/span&gt;                

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;call&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;env&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;status&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;response&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='vi'&gt;@app&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;call&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;env&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Content-Length&amp;quot;&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;length&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_s&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;status&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='mi'&gt;201&lt;/span&gt;
      &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='n'&gt;status&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;headers&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;response&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;                
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Then add the following to your &lt;code&gt;config.ru&lt;/code&gt; file:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='nb'&gt;require&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;content_length_fix&amp;#39;&lt;/span&gt; 
&lt;span class='n'&gt;use&lt;/span&gt; &lt;span class='no'&gt;Nginx&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;ContentLengthFix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Rejoice and your 201 responses now have the correct headers set!&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Fixing Long Key Lengths in MySQL</title>
      <link>http://jimneath.org/2010/06/17/fixing-long-key-lengths-in-mysql.html.html</link>
      <pubDate>Thu Jun 17 13:37:32 +0100 2010</pubDate>
      <guid>http://jimneath.org/2010/06/17/fixing-long-key-lengths-in-mysql.html</guid>
      <description>&lt;p&gt;While using &lt;a href='http://github.com/dsboulder/query_reviewer'&gt;Query Reviewer&lt;/a&gt;, I occasionally come across a warning along the lines of the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;2 identical queries Table videos: Long key length &lt;span class='o'&gt;(&lt;/span&gt;768&lt;span class='o'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;With the following explanation:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;The key used &lt;span class='k'&gt;for &lt;/span&gt;the index was rather long, potentially affecting indices in memory
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;To fix this we need to limit the length of our index. We can do this by creating a migration with &lt;code&gt;:length&lt;/code&gt; added to the &lt;code&gt;add_index&lt;/code&gt; method:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;add_index&lt;/span&gt; &lt;span class='ss'&gt;:videos&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:cached_slug&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:length&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;If you&amp;#8217;re indexing more than one column, you can use the following:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='n'&gt;add_index&lt;/span&gt; &lt;span class='ss'&gt;:stories&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='ss'&gt;:title&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:author_name&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:length&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;10&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:author_name&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='mi'&gt;5&lt;/span&gt; &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Hopefully this post will save someone a few minutes.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>5 Rails Plugins to Help Optimize Your MySQL</title>
      <link>http://jimneath.org/2010/06/15/optimise-your-mysql.html.html</link>
      <pubDate>Tue Jun 15 15:03:59 +0100 2010</pubDate>
      <guid>http://jimneath.org/2010/06/15/optimise-your-mysql.html</guid>
      <description>&lt;p&gt;Optimizing your MySQL queries and performance in your rails applicationcan be a real pain. The plugins below help to make things a little easier.&lt;/p&gt;

&lt;h3 id='bullet'&gt;&lt;a href='http://github.com/flyerhzm/bullet/'&gt;Bullet&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://github.com/flyerhzm/bullet/'&gt;Bullet&lt;/a&gt; is a rails plugin, written by &lt;a href='http://www.huangzhimin.com/'&gt;Richard Huang&lt;/a&gt; (&lt;a href='http://twitter.com/flyerhzm'&gt;@flyerhzm&lt;/a&gt;), that helps to kill N+1 queries. It shows you where you should be using &lt;code&gt;:include&lt;/code&gt; in your ActiveRecord calls. Bullet also informs you where you&amp;#8217;re missing counter caches as well as warning you of any unused eager loading.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/flyerhzm/bullet/' class='github'&gt;http://github.com/flyerhzm/bullet/&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='slimscrooge'&gt;&lt;a href='http://github.com/sdsykes/slim_scrooge/'&gt;SlimScrooge&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://github.com/sdsykes/slim_scrooge/'&gt;SlimScrooge&lt;/a&gt; is a plugin by &lt;a href='http://pennysmalls.com/'&gt;Stephen Sykes&lt;/a&gt; (&lt;a href='http://twitter.com/sdsykes'&gt;@sdsykes&lt;/a&gt;), that restricts the columns retrieved in your MySQL queries by learning which attributes are subsequently called on the ActiveRecord model.&lt;/p&gt;

&lt;p&gt;Below is an example, taken from the readme:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='c1'&gt;# 1st request, sql is unchanged but columns accesses are recorded&lt;/span&gt;
&lt;span class='no'&gt;Brochure&lt;/span&gt; &lt;span class='no'&gt;Load&lt;/span&gt; &lt;span class='no'&gt;SlimScrooged&lt;/span&gt; &lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='n'&gt;st&lt;/span&gt; &lt;span class='n'&gt;time&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;27&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;1&lt;/span&gt;&lt;span class='n'&gt;ms&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;   &lt;span class='no'&gt;SELECT&lt;/span&gt; &lt;span class='o'&gt;*&lt;/span&gt; &lt;span class='no'&gt;FROM&lt;/span&gt; &lt;span class='sb'&gt;`brochures`&lt;/span&gt; &lt;span class='no'&gt;WHERE&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;expires_at&lt;/span&gt; &lt;span class='no'&gt;IS&lt;/span&gt; &lt;span class='no'&gt;NULL&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='c1'&gt;# 2nd request, only fetch columns that were used the first time&lt;/span&gt;
&lt;span class='no'&gt;Brochure&lt;/span&gt; &lt;span class='no'&gt;Load&lt;/span&gt; &lt;span class='no'&gt;SlimScrooged&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='n'&gt;ms&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;   &lt;span class='no'&gt;SELECT&lt;/span&gt; &lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expires_at&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;operator_id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt; &lt;span class='no'&gt;FROM&lt;/span&gt; 
&lt;span class='sb'&gt;`brochures`&lt;/span&gt; &lt;span class='no'&gt;WHERE&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;expires_at&lt;/span&gt; &lt;span class='no'&gt;IS&lt;/span&gt; &lt;span class='no'&gt;NULL&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='c1'&gt;# 2nd request, later in code we need another column which causes a reload of all remaining columns&lt;/span&gt;
&lt;span class='no'&gt;Brochure&lt;/span&gt; &lt;span class='no'&gt;Reload&lt;/span&gt; &lt;span class='no'&gt;SlimScrooged&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;0&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;6&lt;/span&gt;&lt;span class='n'&gt;ms&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;comment&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;image_height&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;tel&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;long_comment&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;image_name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;image_width&lt;/span&gt; &lt;span class='no'&gt;FROM&lt;/span&gt; 
&lt;span class='sb'&gt;`brochures`&lt;/span&gt; &lt;span class='no'&gt;WHERE&lt;/span&gt; &lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt; &lt;span class='no'&gt;IN&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;5646&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;5476&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;4562&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;3456&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;4567&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;7355&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

&lt;span class='c1'&gt;# 3rd request&lt;/span&gt;
&lt;span class='no'&gt;Brochure&lt;/span&gt; &lt;span class='no'&gt;Load&lt;/span&gt; &lt;span class='no'&gt;SlimScrooged&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;4&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='mi'&gt;5&lt;/span&gt;&lt;span class='n'&gt;ms&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;   &lt;span class='no'&gt;SELECT&lt;/span&gt; &lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;expires_at&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;operator_id&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
&lt;span class='sb'&gt;`brochures`&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;id&lt;/span&gt; &lt;span class='no'&gt;FROM&lt;/span&gt; &lt;span class='sb'&gt;`brochures`&lt;/span&gt; &lt;span class='no'&gt;WHERE&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;expires_at&lt;/span&gt; &lt;span class='no'&gt;IS&lt;/span&gt; &lt;span class='no'&gt;NULL&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;&lt;a href='http://github.com/sdsykes/slim_scrooge/' class='github'&gt;http://github.com/sdsykes/slim_scrooge/&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='query_reviewer'&gt;&lt;a href='http://github.com/dsboulder/query_reviewer'&gt;Query Reviewer&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://github.com/dsboulder/query_reviewer'&gt;Query Reviewer&lt;/a&gt; by &lt;a href='http://flouri.sh/'&gt;David Stevenson&lt;/a&gt; (&lt;a href='http://twitter.com/dsboulder'&gt;@dsboulder&lt;/a&gt;) of &lt;a href='http://pivotallabs.com'&gt;Pivotal Labs&lt;/a&gt;, is a Rails plugin that adds a div to the top left of the screen that contains lots of useful details regarding the MySQL executed on the current page.&lt;/p&gt;

&lt;p&gt;The plugin makes it easy to view the &lt;code&gt;EXPLAIN&lt;/code&gt; output for each &lt;code&gt;SELECT&lt;/code&gt; query on the page. It also provides ratings and warnings on each query executed on a page.&lt;/p&gt;

&lt;p&gt;&lt;img alt='Query Reviewer' src='/images/posts/2010/06/Picture-7.png' /&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/dsboulder/query_reviewer' class='github'&gt;http://github.com/dsboulder/query_reviewer&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='rails_indexes'&gt;&lt;a href='http://github.com/eladmeidar/rails_indexes/'&gt;Rails Indexes&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://github.com/eladmeidar/rails_indexes/'&gt;Rails Indexes&lt;/a&gt; is a plugin by &lt;a href='http://blog.eizesus.com'&gt;Elad Meidar&lt;/a&gt; (&lt;a href='http://twitter.com/eladmeidar'&gt;@eladmeidar&lt;/a&gt;), that helps to generate a migration containing suggested indexes for your database.&lt;/p&gt;

&lt;p&gt;By running the following rake command:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;rake db:index_migration
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Rails Indexes will generate the example migration containing suggested indexes. While these indexes are a good start, you will probably find that you need some detailed database indexes.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/eladmeidar/rails_indexes/' class='github'&gt;http://github.com/eladmeidar/rails_indexes/&lt;/a&gt;&lt;/p&gt;

&lt;h3 id='ambitious_query_indexer'&gt;&lt;a href='http://github.com/samdanavia/ambitious_query_indexer'&gt;Ambitious Query Indexer&lt;/a&gt;&lt;/h3&gt;

&lt;p&gt;&lt;a href='http://github.com/samdanavia/ambitious_query_indexer'&gt;Ambitious Query Indexer&lt;/a&gt; is an index generating plugin by &lt;a href='http://www.samsworldofno.com'&gt;Sam Phillips&lt;/a&gt; (&lt;a href='http://twitter.com/samsworldofno'&gt;@samsworldofno&lt;/a&gt;). Like Rails Indexes, it generates a migration containing suggested indexes, but it works by analysing all of the queries it can find in your app.&lt;/p&gt;

&lt;p&gt;&lt;a href='http://github.com/samdanavia/ambitious_query_indexer' class='github'&gt;http://github.com/samdanavia/ambitious_query_indexer&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Calculating an Images Orientation using Paperclip</title>
      <link>http://jimneath.org/2010/06/10/calculating-an-images-orientation-using-paperclip.html.html</link>
      <pubDate>Thu Jun 10 12:52:52 +0100 2010</pubDate>
      <guid>http://jimneath.org/2010/06/10/calculating-an-images-orientation-using-paperclip.html</guid>
      <description>&lt;p&gt;If you ever need to know if an image is portrait or landscape in orientation, you can do the following (assuming you have an &lt;code&gt;orientation&lt;/code&gt; attribute on your model:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Image&lt;/span&gt; &lt;span class='o'&gt;&amp;lt;&lt;/span&gt; &lt;span class='no'&gt;ActiveRecord&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Base&lt;/span&gt;
  &lt;span class='c1'&gt;# Paperclip&lt;/span&gt;
  &lt;span class='n'&gt;has_attached_file&lt;/span&gt; &lt;span class='ss'&gt;:file&lt;/span&gt;
  
  &lt;span class='c1'&gt;# Callbacks&lt;/span&gt;
  &lt;span class='n'&gt;before_create&lt;/span&gt; &lt;span class='ss'&gt;:set_orientation&lt;/span&gt;
  
  &lt;span class='kp'&gt;protected&lt;/span&gt;
  
  &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;set_orientation&lt;/span&gt;
    &lt;span class='n'&gt;original_file&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;file&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;to_file&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='ss'&gt;:original&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;dimensions&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Paperclip&lt;/span&gt;&lt;span class='o'&gt;::&lt;/span&gt;&lt;span class='no'&gt;Geometry&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;from_file&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;original_file&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='nb'&gt;self&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;orientation&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;dimensions&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;width&lt;/span&gt; &lt;span class='o'&gt;&amp;gt;&lt;/span&gt; &lt;span class='n'&gt;dimensions&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;height&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='p'&gt;?&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;landscape&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;portrait&amp;#39;&lt;/span&gt;
  &lt;span class='k'&gt;end&lt;/span&gt;
&lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>How To Speed Up Textmate in Large Projects</title>
      <link>http://jimneath.org/2010/03/25/how-to-speed-up-textmate-in-large-projects.html.html</link>
      <pubDate>Thu Mar 25 11:05:03 +0000 2010</pubDate>
      <guid>http://jimneath.org/2010/03/25/how-to-speed-up-textmate-in-large-projects.html</guid>
      <description>&lt;p&gt;You know those times when Textmate beachballs for about 5 seconds when it regains focus, it&amp;#8217;s generally caused by the fact you&amp;#8217;ve got about 16 million folders in your public/system folder used by paperclip.&lt;/p&gt;

&lt;p&gt;Here&amp;#8217;s a quick tip to speed things up by ignoring those folders:&lt;/p&gt;

&lt;p&gt;Open Textmate &lt;strong&gt;Preferences&lt;/strong&gt; and goto the &lt;strong&gt;Advanced&lt;/strong&gt; section. Then click on &lt;strong&gt;Folder References&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img alt='picture 7' src='/images/posts/2010/03/Picture-7.png' /&gt;&lt;/p&gt;

&lt;p&gt;And enter the following in &lt;strong&gt;Folder Pattern&lt;/strong&gt;:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='bash'&gt;!.*/&lt;span class='o'&gt;(&lt;/span&gt;&lt;span class='se'&gt;\.&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;^/&lt;span class='o'&gt;]&lt;/span&gt;*|**log|system**|CVS|_darcs|_MTN|&lt;span class='se'&gt;\{&lt;/span&gt;arch&lt;span class='se'&gt;\}&lt;/span&gt;|blib|.*~&lt;span class='se'&gt;\.&lt;/span&gt;nib|.*&lt;span class='se'&gt;\.&lt;/span&gt;&lt;span class='o'&gt;(&lt;/span&gt;framework|app|pbproj|pbxproj|xcode&lt;span class='o'&gt;(&lt;/span&gt;proj&lt;span class='o'&gt;)&lt;/span&gt;?|bundle&lt;span class='o'&gt;))&lt;/span&gt;&lt;span class='err'&gt;$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Rejoice in the fact that Textmate doesn&amp;#8217;t make you want to cry.&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>

