<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">

  <title>Practice Over Theory</title>
  
  <link href="http://practiceovertheory.com/" />
  <updated>2012-02-05T16:53:29+00:00</updated>
  <id>http://practiceovertheory.com/</id>
  <author>
    <name>Harold Giménez</name>
    
      <email>harold.gimenez@gmail.com</email>
    
  </author>

  
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/practiceovertheory" /><feedburner:info uri="practiceovertheory" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Boston.io Recap</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/arh20jOMKj0/" />
    <updated>2012-02-05T10:59:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2012/02/05/boston-dot-io-recap</id>
    <content type="html">&lt;p&gt;Boston.io took place yesterday at the Microsoft NERD Center. The event is aimed at students in the Greater Boston area who are interested in entrepreneurship and coding, whether that's design, development, or ambidextrous.&lt;/p&gt;

&lt;p&gt;There were technical and talks on every aspect of the stack, from the metal all the way up to serving and consuming APIs and user experience design. There were also some not-so-technical talks about topics like the Boston startup scene, open source and hacker culture.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://bostonio-postgres.herokuapp.com/#1"&gt;My talk&lt;/a&gt; was about PostgreSQL and it focused on how to use SQL to mine data and get information out of it. I stored the twitter stream for about 24 hours prior to the conference and showed how to look at that data showcasing CTEs, Window Functions and other Postgres features. Among the insights we saw that the tweeps who post hashtags and urls the most are spam accounts. Also, the most posted URLs come from shortener services, but also surprised to see livingsocial.com among those. We found other fun facts during the talk too. It went great.&lt;/p&gt;

&lt;p&gt;Hopefully the talk gave a good taste of what you can do with Postgres and SQL. It was SQL heavy, but that did not come without warning&lt;/p&gt;

&lt;blockquote class="twitter-tweet"&gt;&lt;p&gt;boston.io talk ready to go. SQL, do you speak it? After this you will!&lt;/p&gt;&amp;mdash; Harold Giménez (@hgimenez) &lt;a href="https://twitter.com/hgimenez/status/165804224481988608" data-datetime="2012-02-04T14:29:42+00:00"&gt;February 4, 2012&lt;/a&gt;&lt;/blockquote&gt;


&lt;script src="http://practiceovertheory.com//platform.twitter.com/widgets.js" charset="utf-8"&gt;&lt;/script&gt;


&lt;p&gt;Other talks worth mentioning included &lt;a href="http://twitter.com/mikeburns"&gt;Mike Burns&lt;/a&gt;' classic UNIX talk. This time around he used curl, sed and grep to automate a SQL injection attack on a hilarious page he staged for this purpose. &lt;a href="http://twitter.com/sferik"&gt;Erik Michaels-Ober's&lt;/a&gt; talk was also great and surely inspired a few students to put code out there for the world to see. So many great talks altogether though, by people like &lt;a href="http://twitter.com/qrush"&gt;Nick Quaranto&lt;/a&gt; on TDD, &lt;a href="http://twitter.com/r00k"&gt;Ben Orenstein&lt;/a&gt; on vim, &lt;a href="http://twitter.com/bryanl"&gt;Bryan Lyles&lt;/a&gt; on OOP and &lt;a href="http://boston.io/schedule"&gt;more&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Oh, and there was a dude at the afterparty with a heroku shirt. Here's a photo.&lt;/p&gt;

&lt;p&gt;&lt;img src="https://p.twimg.com/Ak2HPjpCIAAyY7y.jpg:large" /&gt;&lt;/p&gt;

&lt;p&gt;Overall a great event; thanks to organizers &lt;a href="http://thoughtbot.com"&gt;thoughtbot&lt;/a&gt; and &lt;a href="http://greenhornconnect.com/"&gt;Greenhorn Connect&lt;/a&gt; and drinkup sponsors &lt;a href="http://hashrocket"&gt;hashrocket&lt;/a&gt; and &lt;a href="http://github.com"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/arh20jOMKj0" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2012/02/05/boston-dot-io-recap/</feedburner:origLink></entry>
  
  <entry>
    <title>SSH Tunnels for Remote Pairing</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/mRr39eXcHac/" />
    <updated>2012-01-27T08:51:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2012/01/27/ssh-tunnels-for-remote-pairing</id>
    <content type="html">&lt;p&gt;Yesterday was a good day. &lt;a href="http://twitter.com/pvh"&gt;@pvh&lt;/a&gt; and I paired for a few
hours, even though we're at opposite coasts.&lt;/p&gt;

&lt;p&gt;Here's what you need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A server somewhere that both pairs have access to. We used an EC2 instance.
We'll use it to meet up and create the tunnel.&lt;/li&gt;
&lt;li&gt;SSH client libs - your should already have this unless you're on windows in
which case you probably want PuTTY.&lt;/li&gt;
&lt;li&gt;Skype for audio.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;As you know, The Internet is made of nodes connected by Tubes. Unfortunately,
there is no tube from your machine to your pair's machine. What we'll do here is
use a third node that has tubes to both of your machines to relay traffic
through, in essence creating an Internet Tube from your machine to your pair's.
This kind of Internet Tube is called a Tunnel. Since we're using SSH to do the
traffic encryption and forwarding, it's an SSH Tunnel. Yes, that's somewhat made
up, but sounds legit!&lt;/p&gt;

&lt;p&gt;&lt;img src="http://doctorwatson.info/images/lolcats/1111%20internet%20tube%20cat.jpg" /&gt;&lt;/p&gt;

&lt;p&gt;As it turns out, setting up a tunnel is fairly simple. For example, let's set
up a tunnel between you and Jane using a remote server saturn.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You: Open up a shell and forward traffic to your local port 9999 over to
Saturn's port 1235:&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;code&gt;
ssh -L 9999:locahost:1235 saturn_user@saturn
&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Jane: Open up a shell and forward traffic from saturn's port 1235 to her port
22&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;code&gt;
ssh -R 1235:localhost:22 saturn_user@saturn
&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You: Open up another shell, and ssh into your local port 9999 specifying a
username on Jane's machine.
&lt;code&gt;
ssh jane_user@jane -p 9999
&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;And you're good to go. Create a shared screen session, open up $EDITOR, use
skype, google hangouts, face time or whatever for audio and start ping ponging.&lt;/p&gt;

&lt;p&gt;The latency was surprisingly minimal. We left this tunnel open most of the day.
It sat idle for periods of time and the connection was left active. All in all,
a great setup.&lt;/p&gt;

&lt;p&gt;If this is something you'll do often, you might as well add a more permanent
configuration to &lt;code&gt;~/.ssh/config&lt;/code&gt;. For example, you might add:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;~/.ssh/config on your machine &lt;/span&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;Host tunnel_to_jane
&lt;/div&gt;&lt;div class='line'&gt;  Hostname saturn
&lt;/div&gt;&lt;div class='line'&gt;  LocalForward 9999:localhost:1235
&lt;/div&gt;&lt;div class='line'&gt;  User saturn_user
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;Host jane
&lt;/div&gt;&lt;div class='line'&gt;  Hostname jane
&lt;/div&gt;&lt;div class='line'&gt;  User jane_user
&lt;/div&gt;&lt;div class='line'&gt;  Port 9999&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Then you'd do, on one terminal, &lt;code&gt;ssh tunnel_to_jane&lt;/code&gt;, and on the
other &lt;code&gt;ssh jane&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And Jane might add:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt;&lt;figcaption&gt;&lt;span&gt;~/.ssh/config on Jane's machine &lt;/span&gt;&lt;/figcaption&gt;
&lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class=''&gt;&lt;div class='line'&gt;Host tunnel_from_you
&lt;/div&gt;&lt;div class='line'&gt;  Hostname saturn
&lt;/div&gt;&lt;div class='line'&gt;  RemoteForward 1235:localhost:22
&lt;/div&gt;&lt;div class='line'&gt;  User saturn_user&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;And she'd just do, &lt;code&gt;ssh tunnel_from_you&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This can be used not ony for remote pairing, but rather to forward &lt;em&gt;any&lt;/em&gt;
traffic on a port, over an SSH encrypted channel, to a remote host. For more
see &lt;code&gt;ssh_config(5)&lt;/code&gt; and &lt;code&gt;ssh(1)&lt;/code&gt;, and happy pairing!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/mRr39eXcHac" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2012/01/27/ssh-tunnels-for-remote-pairing/</feedburner:origLink></entry>
  
  <entry>
    <title>Redis Talk at PostgreSQL Conf West</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/dCo5tv8y-d8/" />
    <updated>2011-09-19T10:00:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2011/09/19/redis-talk-at-postgresql-conf-west</id>
    <content type="html">&lt;p&gt;In case you've missed it so far, PostgreSQL West will take place next week in San Jose, California. You &lt;a href="https://www.postgresqlconference.org/register"&gt;should go&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This weekend I worked on the slides and content for my &lt;a href="https://www.postgresqlconference.org/content/redis-nimble-data-bacon"&gt;Redis talk&lt;/a&gt;. Why would I decide to speak about Redis in a PostgreSQL conference? As it turns out, we've had great success in using Redis to compliment our architecture, not to replace a main data store. I will speak about our experience in scaling out write heavy apps with Redis.&lt;/p&gt;

&lt;p&gt;I will first introduce Redis from a general perspective, and then dig into the data types it offers and the operations it can do on each data type. During the course of the talk, I will demonstrate how we've used certain data types to solve some rather tricky scaling problems: real use cases solving real problems.&lt;/p&gt;

&lt;p&gt;I hope this talk will be entertaining and informative to both DBAs and application developers. I will be sharing the slides here and on &lt;a href="http://twitter.com/hgimenez"&gt;twitter&lt;/a&gt; afterwards, so stay tuned.&lt;/p&gt;

&lt;p&gt;Additionally, on Tuesday I will be teaching a &lt;a href="https://www.postgresqlconference.org/content/introduction-ruby-and-rails-postgresql-harold-gimenez-full-day"&gt;one day workshop on Ruby and Rails with a PostgreSQL focus&lt;/a&gt;. This is the second time I will do this at PostgreSQL conf, the last time being at PostgreSQL conf east in New York City. The class size was small, and the feedback I received was very positive in that attendees got a good grasp of the Ruby programming language and how Rails and Postgres fit in the ecosystem. I hope this time around is even better.&lt;/p&gt;

&lt;p&gt;Hope to see you there.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/dCo5tv8y-d8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2011/09/19/redis-talk-at-postgresql-conf-west/</feedburner:origLink></entry>
  
  <entry>
    <title>PostgreSQL 9.1 Released</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/cxHZWxKS3wQ/" />
    <updated>2011-09-12T09:18:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2011/09/12/postgresql-9-dot-1-released</id>
    <content type="html">&lt;p&gt;Version 9.1 of PostgreSQL was &lt;a href="http://www.postgresql.org/about/news.1349"&gt;released&lt;/a&gt; yesterday.&lt;/p&gt;

&lt;p&gt;Among the exciting new features there is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;pg_basebackup&lt;/code&gt; - this can be used alongside Streaming Replication to perform a backup or clone of your database. I can imagine &lt;a href="http://heroku.com"&gt;heroku&lt;/a&gt; adopting this as an even faster and reliable way to sync your production and staging databases, for example (when and if they upgrade to 9.1). However it can also be used to create plain old tarballs and create standalone backups.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another replication goodie: Synchronous replication. On Postgres 9.0, replication was asynchronous. By enabling synchronous replication, you are basically telling the master database to only report the transaction as committed when the slave(s) have successfully written it to its own journal. You can also control this on a specific session by doing &lt;code&gt;SET synchronous_commit TO off&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The new &lt;code&gt;pg_stat_replication&lt;/code&gt; view displays the replication status of all slaves from a master node.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Unlogged tables. What? Postgres supports unlogged tables now? Yes, it does. They can be used for data you don't necessarily care about, and a crash will truncate all data. They are much faster to write to and could be useful for caching data or keeping stats that can be rebuilt. You can create them like so:&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;UNLOGGED&lt;/span&gt; &lt;span class="n"&gt;some_stats&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;SQL/MED gets the ability to define foreign tables. This is rich. It means that you can define a foreign data wrapper for a different database and access it from Postgres seamlessly. Some hackers have already built &lt;a href="http://wiki.postgresql.org/wiki/Foreign_data_wrappers"&gt;some nifty foreign data wrappers&lt;/a&gt; for mysql, oracle, and even redis and couchdb. Although I'm of the mind that if you're actually using any of these databases to supplement your app's data needs, just talk to them directly from your app. However, it may be possible to write some higher performance reports that use different data sources, and you let Postgres do the heavy lifting of munging all the data together.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You no longer need to specify all columns on a select list from your GROUP BY clause: functionally dependent columns are inferred by the planner, so specifying a primary key is sufficient. I &lt;a href="http://practiceovertheory.com/blog/2009/09/23/postgresql-s-group-by/"&gt;talked about this before&lt;/a&gt;, and it's a cause of great frustration to users coming from MySQL.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There's much more in this release. Here are the &lt;a href="http://www.postgresql.org/docs/9.1/static/release-9-1.html"&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Huge thanks, Postgres hackers!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/cxHZWxKS3wQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2011/09/12/postgresql-9-dot-1-released/</feedburner:origLink></entry>
  
  <entry>
    <title>Design Tweaks</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/Kn4Jmn1Hdx8/" />
    <updated>2011-09-10T13:46:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2011/09/10/design-tweaks</id>
    <content type="html">&lt;p&gt;Today I made a few design tweaks to this blog. The goal is to move a bit away from the stock default octopress theme - but my design chops aren't all that great and I can't really budget the time to do a design from scratch.&lt;/p&gt;

&lt;p&gt;A few simple changes and I'm OK with how it looks for now:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I created the basic font logo that you now see on the header. This was the idea from the beginning, but I never had a chance to include it here. Commit: &lt;a href="https://github.com/hgimenez/practiceovertheory/commit/27d0107fe1165f61cfd72f17717a674575ca4fc9"&gt;27d0107f&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Change the typography in the site, as the original seems a bit heavy for my taste. I started out by using a Helvetica Neue on headers, but decided to go with Antic from the Google web font service. Commits: &lt;a href="https://github.com/hgimenez/practiceovertheory/commit/2dd8f46b46a4c848ea4debbeeeda8e9ce23fcb0a"&gt;2dd8f46b4&lt;/a&gt; and &lt;a href="https://github.com/hgimenez/practiceovertheory/commit/84bad437716a8c0e78b1354b0f61876e1cd9a988"&gt;84bad437&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I wanted something different for that dark background. Went hunting for tiles and patterns. There's good stuff out there, but I settled for the dark wood background found &lt;a href="http://webtreats.mysitemyway.com/8-tileable-dark-wood-texture-patterns/"&gt;here&lt;/a&gt;. Commit: &lt;a href="https://github.com/hgimenez/practiceovertheory/commit/9593a004317f1fdc57a386373b3210262bd029b0"&gt;9593a00431&lt;/a&gt;. At this point, it also made sense to make the header and footer have a light background and dark font.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, added a gradient to the header. Commit &lt;a href="https://github.com/hgimenez/practiceovertheory/commit/fe918b0e9681bbc9c7af21980a4c585698feaf09"&gt;fe918b0e&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I'm fine with the result for now, but will probably revisit soon. Here's a before and after.&lt;/p&gt;

&lt;h3&gt;Before&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://practiceovertheory.com/images/posts/before-resized.png" alt="Before" /&gt;&lt;/p&gt;

&lt;h3&gt;After&lt;/h3&gt;

&lt;p&gt;&lt;img src="http://practiceovertheory.com/images/posts/after-resized.png" alt="After" /&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/Kn4Jmn1Hdx8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2011/09/10/design-tweaks/</feedburner:origLink></entry>
  
  <entry>
    <title>You Should Work for These Guys</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/SXWpQI-pGx4/" />
    <updated>2011-09-07T13:42:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2011/09/07/you-should-work-for-these-guys</id>
    <content type="html">&lt;p&gt;For the last few months &lt;a href="http://thoughtbot.com"&gt;we've&lt;/a&gt; been working for an awesome company on a greenfield project here in Boston/Cambridge.&lt;/p&gt;

&lt;p&gt;The industry: Healthcare. The goal: Improve patient's lives by changing the way &lt;em&gt;the entire system&lt;/em&gt; works. It's exciting, and it is happening, and you can be a part of it.&lt;/p&gt;

&lt;h3&gt;The stack&lt;/h3&gt;

&lt;p&gt;Rails 3.1, Backbone.js, Coffeescript, faye, PostgreSQL, Cucumber, RSpec and Jasmine.&lt;/p&gt;

&lt;h3&gt;The process&lt;/h3&gt;

&lt;p&gt;Daily standups, TDD, code reviews via github pull requests.&lt;/p&gt;

&lt;h3&gt;The result&lt;/h3&gt;

&lt;p&gt;A highly responsive non-trivial app with a very clean code base and beautiful design.&lt;/p&gt;

&lt;p&gt;The future holds a mobile app, web service integrations and ongoing maintenance to the current code base.&lt;/p&gt;

&lt;p&gt;If you live in the Boston area, you should apply. If you don't, you should move here. &lt;a href="http://thoughtbot.com/jobs/iora/developer/"&gt;Right here&lt;/a&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/SXWpQI-pGx4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2011/09/07/you-should-work-for-these-guys/</feedburner:origLink></entry>
  
  <entry>
    <title>New domain name, new blog engine</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/9jSjJRt6Z48/" />
    <updated>2011-09-06T21:58:00+00:00</updated>
    <id>http://practiceovertheory.com/blog/2011/09/06/new-domain-name</id>
    <content type="html">&lt;p&gt;I haven't touched my blog for a while. Part of it is that I just didn't identify myself with "Awesomeful" any more. On the other hand, have I got a deal for you! Both awesomeful.net and awesomeful.org are for sale, so &lt;a href="http://twitter.com/hgimenez"&gt;hit me up&lt;/a&gt; if you're interested - I'm talking to you mister &lt;code&gt;whois awesomeful.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Welcome to the new blog: &lt;em&gt;Practice Over Theory&lt;/em&gt;. I hope that the new name and engine inspire me to post more often.&lt;/p&gt;

&lt;p&gt;Migrating was not a huge task at all. I decided to give octopress a try. It prescribes a &lt;a href="http://octopress.org/docs/deploying/"&gt;really weird method&lt;/a&gt; of deploying to github pages which involves cloning yourself into a subdirectory (!!), but now I have a pretty neat set up. It's backed by jekyll and has a few nice addons, the most useful of which is it's code highlighting theme which is based on Solarized.&lt;/p&gt;

&lt;p&gt;Speaking of code highlighting, let me show you a little rack app that redirects the old awesomeful.net posts to their new warm locations:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;rubygems&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;sinatra&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;REDIRECTS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class="s1"&gt;&amp;#39;awesomeful-post-1&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;new-location-1&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class="s1"&gt;&amp;#39;awesomeful-post-2&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;new-location-2&amp;#39;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;            &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;freeze&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;get&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/*&amp;#39;&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;path&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;one_year_in_seconds&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;31536000&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;headers&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;Cache-Control&amp;#39;&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;public, max-age=&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;one_year_in_seconds&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="s1"&gt;&amp;#39;Expires&amp;#39;&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;one_year_in_seconds&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;httpdate&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;redirect&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;http://practiceovertheory.com/&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="no"&gt;REDIRECTS&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;301&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Pretty neat, huh? The syntax highlighting, I mean.&lt;/p&gt;

&lt;p&gt;Regarding the above sinatra app, I just have a dictionary[1] mapping the old paths to the new ones, and respond with a &lt;code&gt;HTTP 301 Moved Permanently&lt;/code&gt;. The interesting bit is the HTTP caching employed. Heroku's (awesome) varnish servers will remember that response for one year. Try it &lt;a href="http://awesomeful.net/posts/45-postgresql-rails-and-why-you-should-care"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;[1] it's a hash!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/9jSjJRt6Z48" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2011/09/06/new-domain-name/</feedburner:origLink></entry>
  
  <entry>
    <title>Machine Learning - Who's the Boss?</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/b4gcMob7NfA/" />
    <updated>2010-02-15T20:48:42+00:00</updated>
    <id>http://practiceovertheory.com/blog/2010/02/15/machine-learning-who-s-the-boss</id>
    <content type="html">&lt;p&gt;In the Machine Learning field, there are two types of algorithms that can be applied to a set of data to solve different kinds of problems: &lt;em&gt;Supervised&lt;/em&gt; and &lt;em&gt;Unsupervised&lt;/em&gt; learning algorithms. Both of these have in common that they aim to extract information or gain knowledge from the raw data that would otherwise be very hard and unpractical to do. This is because we live in very dynamic environments with changing parameters and vast amounts of data being gathered. This data hides important patterns and correlations that are sometimes impossible to deduce manually, and where computing power and smart algorithms excel. They are also heavily dependent on the quantity and quality of the input data, and as such, evolve in their output and accuracy as more and better input data becomes available.&lt;/p&gt;

&lt;p&gt;In this article we will walk through what constitues Supervised and Unsupervised Learning. An overview of the language and terms is presented, as well as the general workflow used for machine learning tasks.&lt;/p&gt;

&lt;h3&gt;Supervised Learning&lt;/h3&gt;

&lt;p&gt;In supervised machine learning we have a set of data points or &lt;em&gt;observations&lt;/em&gt; for which we know the desired output, class, &lt;em&gt;target variable&lt;/em&gt;  or &lt;em&gt;outcome&lt;/em&gt;. The outcome may take one of many values called &lt;em&gt;classes&lt;/em&gt; or &lt;em&gt;labels&lt;/em&gt;. A classic example is that given a few thousand emails for which we know whether they are spam or ham (their labels), the idea is to create a model that is able to deduce whether new, unsean emails are spam or not. In other words, we are creating a mapping function where the inputs are the email's sender, subject, date, time, body, attachments and other attributes, and the output is a prediction as to whether the email is spam or ham. The &lt;em&gt;target variable&lt;/em&gt; is in fact providing some level of &lt;em&gt;supervision&lt;/em&gt; in that it is used by the learning algorithm to adjust parameters or make decisions that will allow it to predict labels for new data. Finally of note, when the algorithm is predicting labels of observations we call it a &lt;em&gt;classifier&lt;/em&gt;. Some classifiers are also capable of providing a probability of a data point belonging to class in which case it is often referred to a probabilistic model or a regression - not to be confused with a &lt;a href="http://en.wikipedia.org/wiki/Regression_analysis#Regression_models"&gt;statistical regression model&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Lets take this as an example in supervised learning algorithms. Given the following dataset, we want to predict on new emails whether they are spam or not. In the dataset below, note that the last column, &lt;code&gt;Spam?&lt;/code&gt;, contains the labels for the examples.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;td&gt;&lt;b&gt;Subject&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Date&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Time&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Body&lt;/b&gt;&lt;/td&gt; &lt;td&gt;&lt;b&gt;Spam?&lt;/b&gt;&lt;/td&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt; &lt;td&gt;I has the viagra for you&lt;/td&gt; &lt;td&gt;03/12/1992&lt;/td&gt; &lt;td&gt;12:23 pm&lt;/td&gt; &lt;td&gt;Hi! I noticed that you are a software engineer &lt;br/&gt;so here's the pleasure you were looking for...&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Important business&lt;/td&gt; &lt;td&gt;05/29/1995&lt;/td&gt; &lt;td&gt;01:24 pm&lt;/td&gt; &lt;td&gt;Give me your account number and you'll be rich. &lt;/ br&gt; I'm totally serial&lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Business Plan&lt;/td&gt; &lt;td&gt;05/23/1996&lt;/td&gt; &lt;td&gt;07:19 pm&lt;/td&gt; &lt;td&gt;As per our conversation, here's the business plan for our new venture &lt;/ br&gt; Warm regards...&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Job Opportunity&lt;/td&gt; &lt;td&gt;02/29/1998&lt;/td&gt; &lt;td&gt;08:19 am&lt;/td&gt; &lt;td&gt;Hi &lt;name&gt;!&lt;/ br&gt;I am trying to fill a position for a PHP ... &lt;/td&gt; &lt;td&gt;Yes&lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td colspan="5"&gt; [A few thousand rows ommitted] &lt;/td&gt; &lt;/tr&gt;
    &lt;tr&gt; &lt;td&gt;Call mom&lt;/td&gt; &lt;td&gt;05/23/2000&lt;/td&gt; &lt;td&gt;02:14 pm&lt;/td&gt; &lt;td&gt;Call mom. She's been trying to reach you for a few days now&lt;/td&gt; &lt;td&gt;No&lt;/td&gt; &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;A common workflow approach, and one that I've taken for supervised learning analysis is shown in the diagram below:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://img.skitch.com/20100213-djhg1re7gaj83ngygcqgj1jm2d.png"&gt;&lt;/p&gt;

&lt;p&gt;The process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Scale and prepare training data&lt;/em&gt;: First we build input vectors that are appropriate for feeding into our supervised learning algorithm.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Create a training set and a validation set&lt;/em&gt; by randomly splitting the universe of data. The training set is the data that the classifier uses to learn how to classify the data, whereas the validation set is used to feed the already trained model in order to get an error rate (or other measures and techniques) that can help us identify the classifier's performance and accuracy. Typically you will use more training data (maybe 80% of the entire universe) than validation data. Note that there is also &lt;a href="http://en.wikipedia.org/wiki/Cross-validation_(statistics"&gt;cross-validation&lt;/a&gt;), but that is beyond the scope of this article.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Train the model&lt;/em&gt;. We take the training data and we feed it into the algorithm. The end result is a model that has learned (hopefully) how to predict our outcome given new unknown data.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Validation and tuning&lt;/em&gt;: After we've created a model, we want to test its accuracy. It is critical to do this on data that the model has not seen yet - otherwise you are cheating. This is why on step 2 we separated out a subset of the data that was not used for training. We are indeed testing our model's generalization capabilities. It is very easy to learn every single combination of input vectors and their mappings to the output as observed on the training data, and we can achieve a very low error in doing that, but how does the very same rules or mappings perform on new data that may have different input to output mappings? If the classification error of the validation set is very big compared to the training set's, then we have to go back and adjust model parameters. The model will have essentially memorized the answers seen in the training data, loosing its generalization capabilities. This is called &lt;a href="http://en.wikipedia.org/wiki/Overfitting"&gt;&lt;em&gt;overfitting&lt;/em&gt;&lt;/a&gt;, and there are various techniques for overcoming it.&lt;/li&gt;
&lt;li&gt;Validate the model's performance. There are numerous techniques for achieving this, such as &lt;a href="http://en.wikipedia.org/wiki/Receiver_operating_characteristic"&gt;ROC analysis&lt;/a&gt; and many others. The model's accuracy can be improved by changing its structure or the underlying training data. If the model's performance is not satisfactory, change model parameters, inputs and or scaling, go to step 3 and try again.&lt;/li&gt;
&lt;li&gt;Use the model to classify new data. In production. Profit!&lt;/li&gt;
&lt;/ol&gt;


&lt;h3&gt;Unsupervised Learning&lt;/h3&gt;

&lt;p&gt;The kinds of problems that are suited for unsupervised algorithms may seem similar, but are very different to supervised learners. Instead of trying to predict a set of known classes, we are trying to identify the patterns inherent in the data that separate like observations in one way or another. Viewed from 20 thousand feet, the main difference is that we are not providing a target variable like we did in supervised learning.&lt;/p&gt;

&lt;p&gt;This marks a fundamental difference in how both types of algorithms operate. On one hand, we have supervised algorithms which try to minimize the error in classifying observations, while unsupervised learning algorithms don't have such luxuries because there are no outcomes or labels. Unsupervised algorithms try to create clusters of data that are inherently similar. In some cases we don't necessarily know what makes them similar, but the algorithms are capable of finding these relationships between data points and group them in significant ways. While supervised algorithms aim to minimize the classification error, unsupervised algorithms aim to create groups or subsets of the data where data points belonging to a cluster are as similar to each other as possible, while making the difference between the clusters as high as possible.&lt;/p&gt;

&lt;p&gt;Another main difference is that in a clustering problem, the concept of "Training Set" does not apply in the same way as with supervised learners. Typically we have a dataset that is used to find the relationships in the data that buckets them in different clusters. We could of course apply the same clustering model to new data, but unless it is too unpractical to do so (perhaps for performance reasons), we will most certainly want to rerun the algorithm on new data as it will typically find new relationships within the data that may surface up given the new observations.&lt;/p&gt;

&lt;p&gt;As a simple example, you could imagine clustering customers by their demographics. The learning algorithm may help you discover distinct groups of customers by region, age ranges, gender and other attributes in such way that we can develop targeted marketing programs. Another example may be to cluster patients by their chronic diseases and comorbidities in such a way that targeted interventions can be developed to help manage their diseases and improve their lifestyles.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://img.skitch.com/20100215-qm59id21fs2kr2m1r2sc5umwgw.png"&gt;&lt;/p&gt;

&lt;p&gt;For unsupervised learning, the process is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;em&gt;Scale and prepare raw data&lt;/em&gt;: As with supervised learners, this step entails selecting features to feed into our algorithm, and scaling them to build a suitable data set.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Build model&lt;/em&gt;: We run the unsupervised algorithm on the scaled dataset to get groups of like observations.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Validate&lt;/em&gt;: After clustering the data, we need to verify whether it cleanly separated the data in significant ways. This includes calculating a set of statistics on the resulting clusters (such as the within group sum of squares), as well as analysis based on domain knowledge, where you may measure how certain attributes behave when aggregated by the clusters.&lt;/li&gt;
&lt;li&gt;Once we are satisfied with the clusters created there is no need to run the model with new data (although you can). Profit!&lt;/li&gt;
&lt;/ol&gt;


&lt;h4&gt;Step zero&lt;/h4&gt;

&lt;p&gt;A common step that I have not outlined above and should be performed when working on any such problem is to get a strong understanding for the characteristics of the data. This should be a combination of visual analysis (for which I prefer the excellent &lt;a href="http://had.co.nz/ggplot2/"&gt;ggplot2&lt;/a&gt; library) as well as some basic descriptive statistics and data profiling such as quartiles, means, standard deviation, frequencies and others. &lt;a href="http://www.r-project.org"&gt;R&lt;/a&gt;'s &lt;a href="http://cran.r-project.org/web/packages/Hmisc/index.html"&gt;Hmisc&lt;/a&gt; package has a great function for this purpose called &lt;a href="http://lib.stat.cmu.edu/S/Harrell/help/Hmisc/html/describe.html"&gt;&lt;code&gt;describe&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am convinced that not performing this step is a non starter for any datamining project. It will allow you to identify missing values, general distributions of data, early outlier detection, among many other characteristics that drive the selection of attributes for your models.&lt;/p&gt;

&lt;h3&gt;Wrapping up&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://televixen.files.wordpress.com/2009/02/wtb.jpg"&gt;&lt;img src="http://televixen.files.wordpress.com/2009/02/wtb.jpg"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is certainly quite a bit of info, especially if these terms are new to you. To summarize:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;/td&gt;
      &lt;td&gt;&lt;b&gt;Supervised Learning&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;&lt;b&gt;Unsupervised Learning&lt;/b&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Objective&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Classify or predict a class.&lt;/td&gt;
      &lt;td&gt;Find patterns inherent to the data, creating cluster of like data points. &lt;a href="http://en.wikipedia.org/wiki/Dimension_reduction"&gt;Dimensionality Reduction&lt;/a&gt;.&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Example Implementations&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;Neural Networks (&lt;a href="http://en.wikipedia.org/wiki/Multilayer_perceptron"&gt;Multilayer Perceptrons&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Radial_basis_function_network"&gt;RBF Networks&lt;/a&gt; and others, &lt;a href="http://en.wikipedia.org/wiki/Support_vector_machine"&gt;Support Vector Machines&lt;/a&gt;, Decision Trees (&lt;a href="http://en.wikipedia.org/wiki/ID3_algorithm"&gt;ID3&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/C4.5_algorithm"&gt;C4.5&lt;/a&gt; and others), &lt;a href="http://en.wikipedia.org/wiki/Naive_Bayes_classifier"&gt;Naive Bayes Classifiers&lt;/a&gt;...&lt;/td&gt;
      &lt;td&gt;&lt;a href="http://en.wikipedia.org/wiki/K-means_clustering"&gt;K-Means&lt;/a&gt; (and variants), &lt;a href="http://en.wikipedia.org/wiki/Cluster_analysis#Hierarchical_clustering"&gt;Hierarchical Clustering&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Self-organizing_map"&gt;Kohonen Self Organizing Maps&lt;/a&gt;...&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;b&gt;Who's the Boss?&lt;/b&gt;&lt;/td&gt;
      &lt;td&gt;The target variable or outcome.&lt;/td&gt;
      &lt;td&gt;The relationships inherent to the data.&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;


&lt;p&gt;Hopefuly this article shows the main differences between Unsupervised and Supervised Learning. On followup posts we will dig into some of the specific implementations of these algorithms with examples in &lt;a href="http://www.r-project.org"&gt;R&lt;/a&gt; and &lt;a href="http://ruby-lang.org"&gt;Ruby&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/b4gcMob7NfA" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2010/02/15/machine-learning-who-s-the-boss/</feedburner:origLink></entry>
  
  <entry>
    <title>Experiences porting a helper plugin to Rails 3</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/Im8lnGxQBdY/" />
    <updated>2010-01-18T00:55:45+00:00</updated>
    <id>http://practiceovertheory.com/blog/2010/01/18/experiences-porting-a-helper-plugin-to-rails-3</id>
    <content type="html">&lt;p&gt;Today I spent a few minutes porting &lt;a href="http://github.com/hgimenez/truncate_html"&gt;truncate_html&lt;/a&gt; to Rails 3. This gem/plugin provides you with the &lt;code&gt;truncate_html()&lt;/code&gt; helper method, which is very similar to rails' &lt;code&gt;truncate()&lt;/code&gt;, but it takes care of closing open html tags and other peculiarities of truncating HTML. It works by using regular expressions and does not have any dependencies. I use this gem on this blog, as well as on the &lt;a href="http://bostonrb.org"&gt;bostonrb.org&lt;/a&gt; site. Some other people have found it to be &lt;a href="http://twitter.com/dolzenko/status/6428360551"&gt;useful&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One of the promises of Rails 3 is that there is an &lt;a href="http://www.engineyard.com/blog/2010/rails-and-merb-merge-plugin-api-part-3-of-6/"&gt;API for plugin developers&lt;/a&gt; that will allow you to hook into the right parts of Rails to add the functionality that your plugin provides. This means that you should not be mixing in or monkeypatching Rails core willy-nilly. In fact, it is now expected for you as a plugin developer to figure out how to hook into the right parts of Rails using the new API, as opposed to doing something like the following:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;ActionView&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;TruncateHtmlHelper&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;At this stage, there isn't much documentation around what the API actually is. But this shouldn't stop you from investigating and finding out. In this case, cloning the rails repo and using ack pointed me towards &lt;a href="http://github.com/rails/rails/blob/master/actionpack/lib/action_controller/metal/helpers.rb#L6-39"&gt;actionpack/lib/action_controller/metal/helpers.rb&lt;/a&gt;, where I found all the info I needed to remove the now outdated meta-programmed mixin technique of the dark Rails 2 days. From the docs:&lt;/p&gt;

&lt;blockquote&gt;&lt;pre&gt;
In addition to using the standard template helpers provided in the Rails framework,
creating custom helpers to extract complicated logic or reusable functionality is strongly
encouraged. By default, the controller will include a helper whose name matches that of
the controller, e.g., MyController will automatically include MyHelper.

Additional helpers can be specified using the helper class method in
ActionController::Base or any controller which inherits from it.
&lt;/pre&gt;&lt;/blockquote&gt;


&lt;p&gt;Perfect. All I need to do in this case is &lt;a href="http://github.com/hgimenez/truncate_html/commit/5a33e52db3297a1b35af224d468636e2e68ecdc4"&gt;call the &lt;code&gt;helper&lt;/code&gt; class method with my helper's module&lt;/a&gt;: &lt;code&gt;ActionController::Base.helper(TruncateHtmlHelper)&lt;/code&gt;. A quick run through the app demonstrates however that we now need to mark strings as html_safe. Fine, let's &lt;a href="http://github.com/hgimenez/truncate_html/commit/7539b71f3c572f81ed890d2a9e9156ff51408e2b"&gt;do that&lt;/a&gt;: &lt;code&gt; (TruncateHtml::HtmlTruncator.new(html).truncate(options)).html_safe!&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Finally, let's run the test suite - and &lt;em&gt;facepalm&lt;/em&gt;. The way this plugin is set up is that RSpec must be installed in the containing app for it to run the spec suite. Here's where I ran into the first real issue with the upgrade: I have not been able to install RSpec on a Rails 3 app. I also can't find any obvious way to do it by browsing its source code. For now I seem to be stuck in limbo land until the &lt;a href="http://blog.davidchelimsky.net/2010/01/12/rspec-2-and-rails-3/"&gt;the RSpec/Rails 3 affair&lt;/a&gt; is all sorted out.&lt;/p&gt;

&lt;h3&gt;Backward Compatibility&lt;/h3&gt;

&lt;p&gt;The bigger question is how to maintain backward compatibility. One way to accomplish this is to continue to maintain two git branches for Rails2 and Rails3 (master), and cherry-picking any bug fixes or enhancements from the master branch into the Rails2 branch. However, how could we manage gem bundling and distribution of two gems built for two version of Rails? I'd like to know how you are planning on maintaining backward compatibility. In this particular case, I almost don't care for backward compatibility, and users will simply have to know that version 0.2.2 of the gem is the latest working Rails 2 version, and must install that specific version when running under Rails 2.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/Im8lnGxQBdY" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2010/01/18/experiences-porting-a-helper-plugin-to-rails-3/</feedburner:origLink></entry>
  
  <entry>
    <title>Spec your yields in RSpec</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/xEi_iXRRrWU/" />
    <updated>2009-09-26T00:31:37+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/09/26/spec-your-yields-in-rspec</id>
    <content type="html">&lt;p&gt;Message expectations in RSpec's Mocking/Stubing framework provide means for spec'ing the yielded objects of a method. For example, consider the following spec where we expect the &lt;code&gt;here_i_am&lt;/code&gt; method to &lt;code&gt;yield self&lt;/code&gt;:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Triviality&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#here_i_am&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:triviality&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Triviality&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;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;yields self&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:here_i_am&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;here_i_am&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Nice and easy. First we set the expectation and then we exercise the method so that the expectation is met, passing it a "no op" block - &lt;code&gt;{}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Here's the method to make it pass.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Triviality&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;here_i_am&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Furthermore, we can test many yielded values by chaining the &lt;code&gt;and_yield&lt;/code&gt; method on the expectation. Let's add a spec for a method  that yields many times and see how that would play out:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Triviality&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#one_two_three&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:triviality&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Triviality&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;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;yields the numbers 1, 2 and 3&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:one_two_three&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_yield&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;and_yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;one_two_three&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;And the method to make that pass:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Triviality&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;one_two_three&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This is kind of ugly though. What if it yields many more times, or if you just want to test that it yields all items of an array? A good example of this is the Enumerable's &lt;code&gt;each&lt;/code&gt; method. In such cases we can store the &lt;code&gt;MessageExpectation&lt;/code&gt; object and call &lt;code&gt;and_yield&lt;/code&gt; on it many times, in a loop. Take a look at the following example where we yield each letter of the alphabet:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;Triviality&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;#alphabet&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;let&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:triviality&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Triviality&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;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;yields all letters of the alphabet&amp;#39;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="n"&gt;expectation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should_receive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:alphabet&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Z&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&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="n"&gt;letter&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;expectation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;and_yield&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="n"&gt;triviality&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alphabet&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;And finally, the method to make it pass:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Triviality&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;alphabet&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;A&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;.&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;Z&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;letter&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;letter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;and_yield&lt;/code&gt; is not only useful for message expectations. You can also use it on your &lt;code&gt;stubs&lt;/code&gt;, just like you'd use &lt;code&gt;and_returns&lt;/code&gt;.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/xEi_iXRRrWU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/09/26/spec-your-yields-in-rspec/</feedburner:origLink></entry>
  
  <entry>
    <title>An object quacks like a duck</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/s7Udjqz4stg/" />
    <updated>2009-09-25T01:58:19+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/09/25/an-object-quacks-like-a-duck</id>
    <content type="html">&lt;p&gt;I've been toying around with the idea of spec'ing mixins: that a class includes a module. Suppose the following class:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FooList&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;Enumerable&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="kp"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:some_array&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&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;opts&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="vi"&gt;@some_array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;opts&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:the_array&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[]&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;each&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="vi"&gt;@some_array&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="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="k"&gt;yield&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;We can test the behavior of the &lt;code&gt;each&lt;/code&gt; method using RSpec, but we can also make sure that &lt;code&gt;FooList&lt;/code&gt; actually acts like an &lt;code&gt;Enumerable&lt;/code&gt;. Here's a quick RSpec Matcher just for that (&lt;code&gt;require&lt;/code&gt; it in your spec_helper.rb)&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;Spec&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Matchers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;define&lt;/span&gt; &lt;span class="ss"&gt;:quack_like&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;mod&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;match&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;instance&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;instance_methods&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="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;accum&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;accum&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;failure_message_for_should&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;instance&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="s2"&gt;&amp;quot;expected the class &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; to include the module &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;failure_message_for_should_not&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;instance&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="s2"&gt;&amp;quot;expected the class &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;instance&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not to include the module &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;mod&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;description&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="s2"&gt;&amp;quot;expected the class to behave like a module by responding to all of its instance methods&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This allows us to spec some quacking:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;describe&lt;/span&gt; &lt;span class="no"&gt;FooList&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;foo_list&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="vi"&gt;@foo_list&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="no"&gt;FooList&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;new&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;quacks like an Enumerable&amp;quot;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;foo_list&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;should&lt;/span&gt; &lt;span class="n"&gt;quack_like&lt;/span&gt; &lt;span class="no"&gt;Enumerable&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;I am still experimenting with this. In a way it is not really testing behavior, but it's not really testing the implementation either. In other words, if every method in &lt;code&gt;Enumerable&lt;/code&gt; is implemented in &lt;code&gt;FooList&lt;/code&gt; and we remove the &lt;code&gt;include Enumerable&lt;/code&gt; line, the spec still passes.&lt;/p&gt;

&lt;p&gt;I've discussed this over IRC with some other &lt;a href="http://technicalpickles.com/"&gt;smart&lt;/a&gt; &lt;a href="http://www.enlightsolutions.com/"&gt;folks&lt;/a&gt;, but I want more input . Do you think this is appropriate? Useless?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/s7Udjqz4stg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/09/25/an-object-quacks-like-a-duck/</feedburner:origLink></entry>
  
  <entry>
    <title>PostgreSQL's group by</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/oBQ45hyWyVw/" />
    <updated>2009-09-23T21:30:53+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/09/23/postgresql-s-group-by</id>
    <content type="html">&lt;p&gt;Last night I noticed a user on IRC complaint on two different channels (#heroku and #rubyonrails) claiming something along the lines of "PostgreSQL sucks: i have this code&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;named_scope&lt;/span&gt; &lt;span class="ss"&gt;:with_questions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="ss"&gt;:joins&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:questions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="ss"&gt;:group&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;categories.id, categories.name, categories.created_at, categories.updated_at&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt; because of the way postgresql handles group by. It should only be &lt;code&gt;"categories.id"&lt;/code&gt;."&lt;/p&gt;

&lt;p&gt;The user was surprised that this query works on MySQL. Surely, the user was getting the PostgreSQL message: &lt;code&gt;ERROR: column "categories.name" must appear in the group by clause or be used in an aggregate function&lt;/code&gt;. It turns out that this is not a bug, and PostgreSQL does not suck as this user initially thought. Furthermore, I tried a similar query on MS SQL Server, and it rightfully complaints: &lt;code&gt;Column 'categories.name' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's look at solutions.&lt;/p&gt;

&lt;h4&gt;Alternative Queries&lt;/h4&gt;

&lt;p&gt;The first thing that's wrong about this query is that what the user really wanted was a distinct list of categories that had questions. This is the requirement. To that end, the query should look something like the following two options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Option 1: Drop the &lt;code&gt;join&lt;/code&gt; and &lt;code&gt;group by&lt;/code&gt;, and just use a condition checking whether a question exists for the category:&lt;/li&gt;
&lt;/ul&gt;


&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class="s1"&gt;&amp;#39;exists (select 1 from questions where categories.id = questions.category_id)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;A variation of this can be achieved with the &lt;code&gt;in&lt;/code&gt; operator:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class="s1"&gt;&amp;#39;clients.id in (select client_id from questions)&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Option 2: Again, drop the &lt;code&gt;group by&lt;/code&gt;, and use a &lt;code&gt;distinct&lt;/code&gt; instead:&lt;/li&gt;
&lt;/ul&gt;


&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;Category&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:select&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;distinct items.*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;             &lt;span class="ss"&gt;:joins&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:questions&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h4&gt;&lt;em&gt;Why&lt;/em&gt; PostgreSQL doesn't like the original query&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;group by&lt;/code&gt; clause is used to collect data from multiple records having common values in a select statement, and project the result based on some aggregate function. It really does not make any sense to add a &lt;code&gt;group by&lt;/code&gt; to a query that does not have an aggregate such as &lt;code&gt;sum()&lt;/code&gt;, &lt;code&gt;avg()&lt;/code&gt;, &lt;code&gt;min()&lt;/code&gt;, &lt;code&gt;max()&lt;/code&gt;, &lt;code&gt;count()&lt;/code&gt;. There is an exception, but we'll talk about that later.&lt;/p&gt;

&lt;p&gt;As an example, we could retrieve every item along with a count of categories per item:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;inner&lt;/span&gt; &lt;span class="k"&gt;join&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;categories&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;item_id&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Note that every non-aggregated column on the &lt;code&gt;select&lt;/code&gt; list must appear on the &lt;code&gt;group by&lt;/code&gt; list. This is necessary for PostgreSQL to know which item's to &lt;code&gt;count&lt;/code&gt; on (or &lt;code&gt;sum&lt;/code&gt;, or calculate the &lt;code&gt;max&lt;/code&gt; on). Let's walk through a simplified example of what happens if we don't include one of these columns on the &lt;code&gt;group by&lt;/code&gt; list.&lt;/p&gt;

&lt;p&gt;Suppose the following table&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/p&gt;

&lt;h2&gt;code | city&lt;/h2&gt;

&lt;p&gt;0    | Cambridge
0    | Boston
1    | Foxboro
&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What happens if we run the following query:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='sql'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;group&lt;/span&gt; &lt;span class="k"&gt;by&lt;/span&gt; &lt;span class="n"&gt;code&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;What would you expect PostgreSQL to return for the row with a code equal to 0? Cambridge or Boston? When PostgreSQL is presented with an ambiguous query such as the above, it will stop and report an error. Some other databases may go on and make their own decision as to what to return. To me, this is a broken spec. Futhermore, the result set may be inconsistent and unpredictable across DBMSes, or even queries on the same DB.&lt;/p&gt;

&lt;h4&gt;Exception to the rule&lt;/h4&gt;

&lt;p&gt;On previous versions of PostgreSQL (pre 8.2), the query plan for a &lt;code&gt;group by&lt;/code&gt; was much more efficient than a &lt;code&gt;select distinct&lt;/code&gt;. In some older Rails apps, we wrote things like the following to optimize performance:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;Question&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="ss"&gt;:all&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class="ss"&gt;:group&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Question&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;column_names&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;, &amp;#39;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Instead of the more natural:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="no"&gt;Question&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="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class="ss"&gt;:select&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;distinct items.*&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;              &lt;span class="ss"&gt;:conditions&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;...&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This was an optimization that was specific to our environment and helped us avoid the relatively poor query plan and expensive &lt;code&gt;Seq Scan&lt;/code&gt; that was slowing our app down.&lt;/p&gt;

&lt;object width="560" height="340"&gt;&lt;param name="movie" value="http://www.youtube.com/v/XODMtOqmb9U&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/XODMtOqmb9U&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="560" height="340"&gt;&lt;/embed&gt;&lt;/object&gt;


&lt;p&gt;I hope that after reading this you realize that this error is helping you as a user write better SQL. Complaining that the example query doesn't run on PostgreSQL is like complaining that your new &lt;a href="http://www.fender.com/products//search.php?partno=0110100747"&gt;Fender Strat&lt;/a&gt; sucks because when you play &lt;em&gt;Here comes the Sun&lt;/em&gt; the very same way you played it on your &lt;a href="http://www.thebeatlesrockband.com/"&gt;Beatles Rock Band&lt;/a&gt; guitar, it doesn't sound the same. &lt;code&gt;/endrant&lt;/code&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/oBQ45hyWyVw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/09/23/postgresql-s-group-by/</feedburner:origLink></entry>
  
  <entry>
    <title>Three ActiveRecord model utility methods</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/puy0vInUEW8/" />
    <updated>2009-09-01T00:40:34+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/09/01/three-activerecord-model-utility-methods</id>
    <content type="html">&lt;p&gt;Lately I've found myself implementing at least two out of three of these utility methods on most of my ActiveRecord models on my Rails apps. These methods leverage functionality of either Ruby by itself or Rails that will become helpful in other parts of your application.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.flickr.com/photos/adams_views/3096986188/"&gt;&lt;img src="http://farm4.static.flickr.com/3057/3096986188_0599337f47.jpg" title="Visit original on Flickr"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;The labeler: #to_s&lt;/h3&gt;

&lt;p&gt;  Defining a to_s method enables a very clean way to display a label that represents your model instance. Suppose you have a Post model. You could define a #to_s method similar to the following:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_s&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;title&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Now your views can simply do something like the following HAML:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='haml'&gt;&lt;div class='line'&gt;&lt;span class="nc"&gt;.post&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="nc"&gt;.h2&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@post&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h3&gt;The quantifier: #&amp;lt;=&gt;&lt;/h3&gt;

&lt;p&gt;This method is useful when you consistently need to be able to respond to the question "Which of these is bigger/better/taller/fatter/purtier?". Which metric defines the quantity is completely up to you, but what's important is that defining this method will allow you to call the &lt;code&gt;Enumerable&lt;/code&gt; goodies &lt;code&gt;#min&lt;/code&gt;, &lt;code&gt;#max&lt;/code&gt;, and &lt;code&gt;#sort&lt;/code&gt;. For example, and following the Post model example above, you could imagine the following method definition.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;&amp;lt;=&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;rating&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;other&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;rating&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Assuming you have a &lt;code&gt;recent&lt;/code&gt; named_scope that returns the latest &lt;code&gt;n&lt;/code&gt; posts, you could do things like &lt;code&gt;Post.recent.max&lt;/code&gt; or &lt;code&gt;Post.recent.sort&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;The SEOer: #to_param&lt;/h3&gt;

&lt;p&gt;Finally, this method is leveraged by Rails itself. You can take advantage of the fact that the :id parameter on Rails URLs can be any sequence of integers followed by any non-whitespace characters. Rails will ignore any character after the integers, and use that as the :id parameter. It is customary to use the post's title as part of the URL. An easy way to achieve this in Rails is to define the following method on your model:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_param&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&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;title&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;parameterize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Rails will call to to_param method when using &lt;code&gt;post_url(@post)&lt;/code&gt;, and your URLs shal become &lt;em&gt;slugs&lt;/em&gt;, in SEO terms.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/puy0vInUEW8" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/09/01/three-activerecord-model-utility-methods/</feedburner:origLink></entry>
  
  <entry>
    <title>On the subject of Enterprise Reporting</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/aTeVgFBJEss/" />
    <updated>2009-08-27T00:04:12+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/08/27/on-the-subject-of-enterprise-reporting</id>
    <content type="html">&lt;p&gt;Apparently this is how reporting works in big corporate environments.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We have a bunch of data, terabytes. There's got to be something in there.&lt;/li&gt;
&lt;li&gt;After a few months of cranking, the analyst comes up with a one page report with significant statistics and a couple of charts. This is the first, alpha version of the report.&lt;/li&gt;
&lt;li&gt;Manager receives report. Loves it, since it's the first time they can see the deficiencies in the overall system, and sees opportunities for savings, optimization, improvement.&lt;/li&gt;
&lt;li&gt;Manger passes it along to another set of managers, maybe by region, for constructive feedback.&lt;/li&gt;
&lt;li&gt;A few weeks later, all feedback is taken in, and the analyst implements all of the new requirements into the new, 40 page report.&lt;/li&gt;
&lt;li&gt;Report is sent out quarterly, where it sits on top of a pile labeled TO READ.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2604/3859340277_0bae706b4a.jpg" width="500" height="365" alt="On the subject of Enterprise Reporting" /&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/aTeVgFBJEss" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/08/27/on-the-subject-of-enterprise-reporting/</feedburner:origLink></entry>
  
  <entry>
    <title>Small collection of useful vim tricks</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/AFWuH-SlrqE/" />
    <updated>2009-08-18T20:44:42+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/08/18/small-collection-of-useful-vim-tricks</id>
    <content type="html">&lt;p&gt;I've been using vim for the past couple of years. Vim is a cross-platform programmer's editor that is highly customizable and has a ton of well known and not-so well known features. As time goes by, I always come across new or better ways of doing things that increase productivity. What's most important is to force yourself to start using them so that they become part of your workflow, becoming muscle memory.&lt;/p&gt;

&lt;p&gt;Here's a small collection of tips that I've picked up along the way:&lt;/p&gt;

&lt;h3&gt;Moving around files&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;I never bought into NERDTree or any of the other explorer plugins. I usually jump around using gf, using Rails.vim's &lt;code&gt;:R&lt;/code&gt;, &lt;code&gt;:A&lt;/code&gt;, etc, or you can open up vim's built in explorer using &lt;code&gt;:Ex&lt;/code&gt;. &lt;code&gt;:Sex&lt;/code&gt; opens it up in a split window.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use vim marks to jump around any number of files. Here's a quick &lt;a href="http://www.linux.com/archive/feature/54159"&gt;reference&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;gf&lt;/code&gt; will open the filename under the cursor. &lt;code&gt;Rails.vim&lt;/code&gt; extends this by being smart about view partials. You can also use &lt;code&gt;&lt;C-W&gt;gf&lt;/code&gt; to open the file in a new tab.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use ctags. &lt;code&gt;C-]&lt;/code&gt; on any method name or attribute to jump to the declaration point (or &lt;code&gt;&lt;C-W&gt;-]&lt;/code&gt; to open on a new window. Use &lt;code&gt;&lt;C-T&gt;&lt;/code&gt; to come back. The tag stack is maintained. Then, &lt;code&gt;:ta&lt;/code&gt; to jump to the tag. I use F5 to rebuild my ctags database:
&lt;code&gt;map &lt;silent&gt; &lt;F5&gt;:!ctags -R --exclude=.svn --exclude=.git --exclude=log *&lt;CR&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn how to use windows and tabs: it can really improve your work flow. I usually have multiple tabs open with different areas of the project. On each tab, I may have up to four windows open. I use tabs when it's a different context, for example, a CSS and a view file on one tab, and a controller, cucumber feature and step definitions on another tab, each on its own windows. When working with many windows, it's useful to quickly resize them: &lt;code&gt;&lt;C-W&gt;_&lt;/code&gt; maximizes the viewing area of the active window (for vertical windows, &lt;code&gt;&lt;C-W&gt;|&lt;/code&gt; does the same). You can come back to equally sized windows with &lt;code&gt;&lt;C-W&gt;=&lt;/code&gt;. The easiest way for me to move around tabs is using &lt;code&gt;gt&lt;/code&gt; and &lt;code&gt;gT&lt;/code&gt;. To move around windows, I typically use &lt;code&gt;&lt;C-W&gt;&lt;/code&gt; along with one of h, j, k, l.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;More efficient editing&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automate simple tasks with macros. &lt;code&gt;q{reg}&lt;your-macro&gt;q&lt;/code&gt;. Then invoke it &lt;em&gt;n&lt;/em&gt; times with &lt;code&gt;n@{reg}&lt;/code&gt;. Learn about &lt;a href="http://vim.wikia.com/wiki/Record_a_recursive_macro"&gt;recursive macros&lt;/a&gt; to run it until EOF.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use your registers. Yanking (and putting) and recording macros to different registers is most useful. Use &lt;code&gt;:reg&lt;/code&gt; to view contents of your registers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quickly change text surrounded by &lt;em&gt;something&lt;/em&gt; using &lt;code&gt;ci&lt;/code&gt;. For example, to change a string in double quotes use &lt;code&gt;ci"&lt;/code&gt;, or to change parenthesized parameters, use &lt;code&gt;ci(&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When working with large number of files, you can run the same command on all buffers/windows/tabs by using &lt;code&gt;:bufdo&lt;/code&gt;/&lt;code&gt;:windo&lt;/code&gt;/&lt;code&gt;:tabdo&lt;/code&gt;. Such a time saver.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn how to use vim's substitute command with regular expressions and the grouping operators \( and \). You can morph a file at will using the matched part of the pattern and \1, \2. Throw &lt;code&gt;i&lt;/code&gt; at the end of the command for interactive substitution. Here's a &lt;a href="http://www.geocities.com/volontir/"&gt;good vim regex guide&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vim's built in autocompletion rocks. Use &lt;code&gt;&lt;C-n&gt;&lt;/code&gt; or &lt;code&gt;&lt;C-p&gt;&lt;/code&gt; in insert mode to activate and move through the options.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When moving within a file, &lt;code&gt;f&lt;char&gt;&lt;/code&gt; moves the cursor forward until the first &lt;code&gt;&lt;char&gt;&lt;/code&gt;. &lt;code&gt;;&lt;/code&gt; repeats the action. You can move to the second occurrence of &lt;code&gt;&lt;char&gt;&lt;/code&gt; by using &lt;code&gt;2f&lt;char&gt;&lt;/code&gt;. &lt;code&gt;F&lt;char&gt;&lt;/code&gt; does the same, but backwards.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn the different ways to enter insert mode. The ones I use the most, other than &lt;code&gt;i&lt;/code&gt; are&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a&lt;/code&gt; to enter insert mode at the next character (as opposed to i, which enters insert mode before the current character).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt; to enter insert mode at the end of the line.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;I&lt;/code&gt; to enter insert mode at the beginning of the line.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;O&lt;/code&gt; to create a new line above the current line and enter insert mode.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;o&lt;/code&gt; to create a new line below the current line and enter insert mode.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Block selection is magical. Use it when you want to select a vertical block or column to yank it, delete it, etc. To enter visual block select, do &lt;code&gt;&lt;C-q&gt;&lt;/code&gt;. You can also insert arbitrary text before the block with &lt;code&gt;&lt;C-I&gt;&lt;type your chars&gt;Esc&lt;/code&gt;. For example, this is very useful for inserting the same text on a set of aligned &lt;code&gt;&lt;li&gt;s&lt;/code&gt;(like adding a class="foo" attribute) or after hash rockets or equal signs on your ruby code - yet another reason to align these properly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;C-e&lt;/code&gt; and &lt;code&gt;C-y&lt;/code&gt;, scrolls the buffer without moving the cursor. Make it scroll three lines at a time with:
&lt;code&gt; nnoremap &lt;C-e&gt; 3&lt;C-e&gt;
nnoremap &lt;C-y&gt; 3&lt;C-y&gt;&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;%&lt;/code&gt; to jump to the matching open or closing bracket/parenthesis. Use the &lt;a href="http://www.vim.org/scripts/script.php?script_id=39"&gt;matchit plugin&lt;/a&gt; to have it match more than single characters, for example &lt;code&gt;def&lt;/code&gt; matches &lt;code&gt;end&lt;/code&gt; in Ruby code, or &lt;code&gt;&lt;ul&gt;&lt;/code&gt; matches &lt;code&gt;&lt;/ul&gt;&lt;/code&gt; in HTML.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Other miscellanea&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;For bash style command tab completion, put &lt;code&gt;set wildmode=list:longest&lt;/code&gt; on your vimrc. Then tab away when running commands on ex mode.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;View unprintable characters with &lt;code&gt;:set list&lt;/code&gt;. Cancel out with &lt;code&gt;:set nolist&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Analyzing log files with vim is also a win. For example, you may be in a rails app and used &lt;code&gt;Rails.vim&lt;/code&gt;'s &lt;code&gt;:Rlog&lt;/code&gt; command. Now you can use the global command to surface up the specific pattern you're looking for using &lt;code&gt;:g/{pattern}/p&lt;/code&gt;, or you may remove any useless lines with &lt;code&gt;:g/{useless}/d&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When pasting something, vim will autoindent which is usually not what you want. Use &lt;code&gt;:set paste&lt;/code&gt; before the paste to avoid that.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;gg=G&lt;/code&gt; to apply proper indentation to a messy source file. I define 2 space "tabs" for all file types by using &lt;code&gt;set tabstop=2 shiftwidth=2 expandtab&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Saving and reopening a vim session is easy using &lt;code&gt;:mksession!&lt;/code&gt; and &lt;code&gt;:source&lt;/code&gt;. I have the following two maps in my vimrc to make this even easier with F2 and F3:
&lt;code&gt;map &lt;F2&gt; :mksession! ~/vim_session &lt;cr&gt; " Quick write session with F2
map &lt;F3&gt; :source ~/vim_session &lt;cr&gt;     " And load session with F3&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;Ctrl-L&lt;/code&gt; to redraw the screen (to fix broken syntax highlighting). The following mapping will also remove highlighting after a search: &lt;code&gt;nnoremap &lt;C-L&gt; :nohls&lt;CR&gt;&lt;C-L&gt;&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;About those darn backup files infecting your project: Keep them, but on a different location - you may come to a crash, and you'll need them. I created a directory called ~/.vim_backups, and vim puts them there. The relevant lines are:
&lt;code&gt; silent execute '!mkdir -p ~/.vim_backups'
set backupdir=~/.vim_backups//
set directory=~/.vim_backups//&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I usually write blog posts in Vim using markdown. I use vim's integrated spell checking by setting &lt;code&gt;:set spellang=en_us&lt;/code&gt; on my vimrc. To invoke it, use &lt;code&gt;:set spell&lt;/code&gt; which will underline misspelled words, and &lt;code&gt;z=&lt;/code&gt; brings up suggestions for the misspelled words under the cursor.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Word wrapping is sluggish by default. I added &lt;a href="http://github.com/hgimenez/vimfiles/blob/c07ac584cbc477a0619c435df26a590a88c3e5a2/vimrc#L72-122"&gt;these lines&lt;/a&gt; to my .vimrc which do a few of things: &lt;code&gt;&lt;leader&gt;w&lt;/code&gt; toggles between wrap and no wrap. It adds a &lt;code&gt;&gt;&lt;/code&gt; character to new lines, making it obvious that you're on a wrapping line. It tries to wrap on word boundaries, and finally, it remaps k and j so that you're moving up/down on visual lines, not actual lines.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;code&gt;set showmatch&lt;/code&gt; and &lt;code&gt;set mat=5&lt;/code&gt; on your .vimrc to blink matching parenthesis or brackets. Unobstrusive and useful.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I am sure I'm missing many, but this is what I use most often. Got any tips worth sharing or even better, improvements to the above?&lt;/p&gt;

&lt;h4&gt;Resources&lt;/h4&gt;

&lt;p&gt;The following are books, tutorials or articles that I've found useful in learning and improving my vim workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://vim.runpaint.org/toc/"&gt;Vim cookbook&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.networkcomputing.com/unixworld/tutorial/009/009.html"&gt;The vi/ex editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jerrywang.net/vi/"&gt;Vi for smarties&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://jmcpherson.org/editing.html"&gt;Efficient editing with vim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.viemu.com/a-why-vi-vim.html"&gt;Why, oh WHY, do those #?@! nutheads use vi?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.swaroopch.com/notes/Vim"&gt;A byte of vim&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/AFWuH-SlrqE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/08/18/small-collection-of-useful-vim-tricks/</feedburner:origLink></entry>
  
  <entry>
    <title>On the subject of e-voting</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/UC1ym7QBCJc/" />
    <updated>2009-08-16T01:52:37+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/08/16/on-the-subject-of-e-voting</id>
    <content type="html">&lt;p&gt;May sound bitter, but this is exactly how I feel about e-voting. Not only are there many &lt;a href="http://en.wikipedia.org/wiki/Electronic_voting#Documented_problems"&gt;documented issues&lt;/a&gt;, but it is just too easy to under/over count. Draw your own conclusions.&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm4.static.flickr.com/3516/3823734007_72df752ec3.jpg" width="500" height="294" alt="On the subject of e-voting" /&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/UC1ym7QBCJc" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/08/16/on-the-subject-of-e-voting/</feedburner:origLink></entry>
  
  <entry>
    <title>On the subject of average body weight by day of the week</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/KODYjc88t2w/" />
    <updated>2009-08-08T03:37:34+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/08/08/on-the-subject-of-average-body-weight-by-day-of-the-week</id>
    <content type="html">&lt;p&gt;I have been diligently keeping track of my weight, every day, for the past 10 years. It's taken significant effort but persistence's my middle name.&lt;/p&gt;

&lt;p&gt;Here's a chart of my average weight by day of the week:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://farm3.static.flickr.com/2524/3799614914_7848ef7b10.jpg" width="500" height="351" alt="on the subject of body weight" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/KODYjc88t2w" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/08/08/on-the-subject-of-average-body-weight-by-day-of-the-week/</feedburner:origLink></entry>
  
  <entry>
    <title>Sortable lists with JQuery in Rails</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/TK47j4Op3_U/" />
    <updated>2009-08-07T05:35:30+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/08/07/sortable-lists-with-jquery-in-rails</id>
    <content type="html">&lt;p&gt;Drag 'n Drop sortable lists are a great way to provide a UI for sorting, well, lists of things. Most Rails examples &lt;a href="http://railscasts.com/episodes/147-sortable-lists"&gt;out&lt;/a&gt; &lt;a href="http://blog.wyeworks.com/2009/7/27/drag-drop-sortable-lists"&gt;in&lt;/a&gt; &lt;a href="http://harryche2008.wordpress.com/2008/07/19/how-to-do-ajax-style-drag-n-drop-sorting-with-rails/"&gt;the&lt;/a&gt; &lt;a href="http://www.devarticles.com/c/a/Ruby-on-Rails/Dropping-and-Sorting-with-AJAX-and-scriptaculous/2/"&gt;wild&lt;/a&gt; use prototype/scriptaculous and the built in Rails javascript helpers. In this walkthrough we'll provide the same functionality using JQuery instead. We will not be using the &lt;a href="http://api.rubyonrails.org/classes/ActionView/Helpers/ScriptaculousHelper.html#M001640"&gt;built in Rails javascript helper&lt;/a&gt;. Instead we'll write Unobstrusive Javascript using JQuery.&lt;/p&gt;

&lt;p&gt;For this example we'll use a UserStory and a Task model:&lt;/p&gt;

&lt;p&gt;&lt;img src="http://yuml.me/diagram/scruffy/class/[UserStory]-&gt;[Task]." /&gt;&lt;/p&gt;

&lt;p&gt;The very first step is to download JQuery into your Rails app, as well as some basic setup that will make our lives easier when dealing with Unobstrusive Javascript (UJS). UJS is overlooked amongst web app developers. It's all about separation of concerns. Remember in the late 80s and 90s when it was common to throw style right there on your HTML with things like &lt;code&gt;color="magenta"&lt;/code&gt; or tags like &lt;code&gt;&lt;center&gt;&lt;/code&gt;? Same thing is happening with Javascript: separate behavior from content and presentation. So instead of saying &lt;code&gt;&lt;a href="#" onclick="some_function()"&gt;foo&lt;/a&gt;&lt;/code&gt;, you want to create a plain old link, and unobstrusively change the click's behavior via javascript. The basic feel for this looks like:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;div class='line'&gt;&lt;span class="c"&gt;&amp;lt;!-- in your view --&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;foo&amp;quot;&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://foo.info&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This is foo!&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;




&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;div class='line'&gt;&lt;span class="c1"&gt;//in application.js (possibly)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#foo&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;click&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="c1"&gt;//handle the click&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;//cancel the browser&amp;#39;s traditional event.&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Just like we use CSS selectors to style an element, we can use JQuery selectors to describe the behavior of the element. Just like you may have &lt;code&gt;styles.css&lt;/code&gt;, you may have &lt;code&gt;application.js&lt;/code&gt;. This separation of behavior helps avoid cross browser inconsistencies, dry up and reuse your code, as well as provide graceful degradation to user agents that don't even support Javascript. For instance, a form may be submitted via AJAX if the browser supports Javascript, or the traditional action may execute if it doesn't. I've come to the point where looking at something like &lt;code&gt;&lt;a href="#" onclick='foo()'&gt;foo&lt;/a&gt;&lt;/code&gt; has the same effect as seeing style code in the middle of an HTML document: &lt;em&gt;repugnance&lt;/em&gt;.&lt;/p&gt;

&lt;h4&gt;Set yourself up for JQuery&lt;/h4&gt;

&lt;p&gt;Head over to &lt;a href="http://jquery.com/"&gt;the JQuery site&lt;/a&gt; and download the minified (production) version of JQuery. The sortable() function is part of &lt;a href="http://jqueryui.com/home"&gt;JQuery UI&lt;/a&gt;, which you can download from &lt;a href="http://jqueryui.com/download"&gt;here&lt;/a&gt;. Place both under public/javascripts and include it on your layouts. Pretty standard stuff.&lt;/p&gt;

&lt;p&gt;Add a content block on your layout for &lt;code&gt;:javascript&lt;/code&gt;. This pattern was picked up while hacking on the &lt;a href="http://bostonrb.org"&gt;bostonrb site's&lt;/a&gt; &lt;a href="http://github.com/bostonrb/bostonrb/blob/bca256689a5e381b1a8e729a9769820322f44cfa/app/views/shared/_javascripts.html.haml#L2"&gt;code&lt;/a&gt; and I've stolen it for my own projects. It is a great way to throw UJS in your views. This should be at the bottom of your layout, right before the closing &lt;code&gt;&lt;/body&gt;&lt;/code&gt; tag (or in it's own partial along with other javascript related stuffs):&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;div class='line'&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;&lt;/span&gt;My boring blog&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    ...
&lt;/div&gt;&lt;div class='line'&gt;    yield :javascript
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Having that out of the way, we need to set up jQuery's AJAX requests. We can use &lt;a href="http://docs.jquery.com/Ajax/jQuery.ajaxSetup"&gt;JQuery's &lt;code&gt;$.ajaxSetup()&lt;/code&gt;&lt;/a&gt; hook to set the appropriate headers. Additionally, we'll include Rails' authenticity token on our AJAX Post requests.&lt;/p&gt;

&lt;p&gt;For this to work, we need to store the Rails authenticity token &lt;em&gt;somewhere&lt;/em&gt;. One option is to simply store it on a javascript variable as described &lt;a href="http://henrik.nyh.se/2008/05/rails-authenticity-token-with-jquery"&gt;here&lt;/a&gt;. Add this to your layout:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;%= javascript_tag &amp;quot;var AUTH_TOKEN =&lt;/span&gt; &lt;span class="c1"&gt;#{form_authenticity_token.inspect};&amp;quot; if protect_against_forgery? %&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Then, throw the following on your public/javascripts/application.js file - I haven't seen any downside to this, but leave a comment if you do.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;span class='line'&gt;18&lt;/span&gt;
&lt;span class='line'&gt;19&lt;/span&gt;
&lt;span class='line'&gt;20&lt;/span&gt;
&lt;span class='line'&gt;21&lt;/span&gt;
&lt;span class='line'&gt;22&lt;/span&gt;
&lt;span class='line'&gt;23&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='javascript'&gt;&lt;div class='line'&gt;&lt;span class="c1"&gt;//public/javascripts/application.js&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="c1"&gt;// This sets up the proper header for rails to understand the request type,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="c1"&gt;// and therefore properly respond to js requests (via respond_to block, for example)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ajaxSetup&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="s1"&gt;&amp;#39;beforeSend&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;xhr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setRequestHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;Accept&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ready&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="c1"&gt;// UJS authenticity token fix: add the authenticy_token parameter&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="c1"&gt;// expected by any Rails POST request.&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="nx"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;ajaxSend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;request&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="c1"&gt;// do nothing if this is a GET request. Rails doesn&amp;#39;t need&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="c1"&gt;// the authenticity token, and IE converts the request method&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="c1"&gt;// to POST, just because - with love from redmond.&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;GET&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;undefined&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;settings&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;amp;&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;authenticity_token=&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nb"&gt;encodeURIComponent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;AUTH_TOKEN&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;Having done that, let's prep our models. Let's assume you've created the &lt;code&gt;UserStory&lt;/code&gt; and &lt;code&gt;Task&lt;/code&gt; classes with the required &lt;code&gt;has_many&lt;/code&gt; and &lt;code&gt;belongs_to&lt;/code&gt; associations.&lt;/p&gt;

&lt;h4&gt;Models set up.&lt;/h4&gt;

&lt;p&gt;The models require just a few things: the acts_as_list plugin and a position attribute on the tasks table&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Install the &lt;a href="http://github.com/rails/acts_as_list/tree/master"&gt;acts_as_list&lt;/a&gt; plugin:&lt;/li&gt;
&lt;/ul&gt;


&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;div class='line'&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;script/plugin install git://github.com/rails/acts_as_list.git
&lt;/div&gt;&lt;div class='line'&gt;Initialized empty Git repository in /Users/hgimenez/code/foo/vendor/plugins/acts_as_list/.git/
&lt;/div&gt;&lt;div class='line'&gt;remote: Counting objects: 13, &lt;span class="k"&gt;done&lt;/span&gt;.
&lt;/div&gt;&lt;div class='line'&gt;remote: Compressing objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;9/9&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;.
&lt;/div&gt;&lt;div class='line'&gt;remote: Total 13 &lt;span class="o"&gt;(&lt;/span&gt;delta 2&lt;span class="o"&gt;)&lt;/span&gt;, reused 0 &lt;span class="o"&gt;(&lt;/span&gt;delta 0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;Unpacking objects: 100% &lt;span class="o"&gt;(&lt;/span&gt;13/13&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="k"&gt;done&lt;/span&gt;.
&lt;/div&gt;&lt;div class='line'&gt;From git://github.com/rails/acts_as_list
&lt;/div&gt;&lt;div class='line'&gt; * branch            HEAD       -&amp;gt; FETCH_HEAD
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="err"&gt;$&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Create a position column on the tasks table with:&lt;/li&gt;
&lt;/ul&gt;


&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='bash'&gt;&lt;div class='line'&gt;script/generate migration add_position_to_tasks
&lt;/div&gt;&lt;div class='line'&gt;rake db:migrate
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Add &lt;code&gt;acts_as_list :scope =&gt; :user_story&lt;/code&gt; to the Task model.&lt;/li&gt;
&lt;li&gt;Optionally, add &lt;code&gt;default_scope =&gt; 'position'&lt;/code&gt; to the Task model.&lt;/li&gt;
&lt;/ul&gt;


&lt;h4&gt;View setup&lt;/h4&gt;

&lt;p&gt;The idea is to create an &lt;code&gt;&lt;ul&gt;&lt;/code&gt; of tasks that belong to a given user story. Each &lt;code&gt;&lt;li&gt;&lt;/code&gt; contains a task and we have to "stage" the element's IDs so that when we serialize the list using JQuery, the task's IDs are sent over to the server via an AJAX request.&lt;/p&gt;

&lt;p&gt;We also create a span with a class of "handle", which is where the user can hold on to when dragging and dropping tasks around.&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='html'&gt;&lt;div class='line'&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;tasks-list&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;% @user_story.tasks.each do |t| %&amp;gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="nt"&gt;&amp;lt;li&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;task_&amp;lt;%= t.id -%&amp;gt;&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;name&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;%= t.name -%&amp;gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;      &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;handle&amp;quot;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;[handle]&lt;span class="nt"&gt;&amp;lt;span&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="nt"&gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="err"&gt;&amp;lt;&lt;/span&gt;% end %&amp;gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="nt"&gt;&amp;lt;ul&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h4&gt;(Unobstrusive) javascript setup&lt;/h4&gt;

&lt;p&gt;Now we are ready to wire in the javascript on your view. At the bottom of your view, and using the &lt;code&gt;:javascript&lt;/code&gt; content block created earlier, use &lt;a href="http://docs.jquery.com/UI/Sortable"&gt;JQuery's sortable()&lt;/a&gt; function and attach it to the #tasks-list element:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;span class='line'&gt;10&lt;/span&gt;
&lt;span class='line'&gt;11&lt;/span&gt;
&lt;span class='line'&gt;12&lt;/span&gt;
&lt;span class='line'&gt;13&lt;/span&gt;
&lt;span class='line'&gt;14&lt;/span&gt;
&lt;span class='line'&gt;15&lt;/span&gt;
&lt;span class='line'&gt;16&lt;/span&gt;
&lt;span class='line'&gt;17&lt;/span&gt;
&lt;span class='line'&gt;18&lt;/span&gt;
&lt;span class='line'&gt;19&lt;/span&gt;
&lt;span class='line'&gt;20&lt;/span&gt;
&lt;span class='line'&gt;21&lt;/span&gt;
&lt;span class='line'&gt;22&lt;/span&gt;
&lt;span class='line'&gt;23&lt;/span&gt;
&lt;span class='line'&gt;24&lt;/span&gt;
&lt;span class='line'&gt;25&lt;/span&gt;
&lt;span class='line'&gt;26&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;% content_for &lt;/span&gt;&lt;span class="ss"&gt;:javascript&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="sx"&gt;%&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="sx"&gt;  &amp;lt;% javascript_tag do %&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;     &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#tasks-list&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sortable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;        &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;axis&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;y&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;dropOnEmpty&lt;/span&gt;&lt;span class="ss"&gt;:false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;handle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;.handle&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;cursor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;crosshair&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;li&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;opacity&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;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;scroll&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;            &lt;span class="vg"&gt;$.&lt;/span&gt;&lt;span class="n"&gt;ajax&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;post&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class="n"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#tasks-list&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;sortable&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;serialize&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;&amp;amp;id=&amp;lt;%=@user_story.id-%&amp;gt;&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class="n"&gt;dataType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;script&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class="n"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;function&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                    &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;#tasks-list&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;effect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;highlight&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;                &lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;/user_stories/prioritize_tasks&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;            &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;          &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sx"&gt;% end %&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="sx"&gt;  &lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="sx"&gt;&amp;lt;% end %&amp;gt;&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This is basically saying: Take the element with an ID of &lt;code&gt;#tasks-list&lt;/code&gt; and make it sortable. Do an &lt;code&gt;HTTP POST&lt;/code&gt; to the &lt;code&gt;user_stories/prioritize_tasks&lt;/code&gt; path with the serialized tasks-lists as data. Note that we're also appending the user_story id as a post parameter so that our controller action knows which tasks to prioritize.&lt;/p&gt;

&lt;p&gt;Feel free to go over the &lt;a href="http://docs.jquery.com/UI/Sortable"&gt;sortable()&lt;/a&gt; documentation to tweak the options.&lt;/p&gt;

&lt;h4&gt;Controller set up&lt;/h4&gt;

&lt;p&gt;The controller's work is to take the parameters sent in from the view and to set the position attribute of each of the user story's tasks. The parameters received in the controller look something like:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;inspect&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;authenticity_token&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;9HJQs99d4vqhLwjPAdC8uSLwjPAd4OpbaJQs99dFCch8XisI=&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;id&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;task&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;=&amp;gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;As expected, we receive the Rails authenticity token, as well as the id (the UserStory ID) and an array of task IDs (&lt;code&gt;params['task']&lt;/code&gt; contains task IDs in the order specified by the user).&lt;/p&gt;

&lt;p&gt;Here's the implementation of the prioritize_tasks action:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;span class='line'&gt;5&lt;/span&gt;
&lt;span class='line'&gt;6&lt;/span&gt;
&lt;span class='line'&gt;7&lt;/span&gt;
&lt;span class='line'&gt;8&lt;/span&gt;
&lt;span class='line'&gt;9&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;prioritize_tasks&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;user_story&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;UserStory&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="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:id&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;tasks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_story&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;tasks&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;tasks&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;each&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;task&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;task&amp;#39;&lt;/span&gt;&lt;span class="o"&gt;].&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;to_s&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;/div&gt;&lt;div class='line'&gt;    &lt;span class="n"&gt;task&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;save&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;render&lt;/span&gt; &lt;span class="ss"&gt;:nothing&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;h4&gt;Route setup&lt;/h4&gt;

&lt;p&gt;Almost there. The one thing that's missing would be adding a collection route to the user_story resource for the prioritize_tasks action:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;  &lt;span class="c1"&gt;# add the :collection option&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;resources&lt;/span&gt; &lt;span class="ss"&gt;:user_story&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:collection&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;:prioritize_tasks&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ss"&gt;:post&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;This pretty much wraps it up! This process will become easier as Rails core evolves and the Javascript framework becomes easier to swap out. It is known that Rails 3's helpers will not produce inline javascript. Instead, they will add hooks to your DOM elements in the form of HTML5's custom data attributes which then can be used by unobstrusive javascript code to add the appropriate behavior to the DOM elements. Even though Rails will continue to ship with the Prototype/Scriptaculous frameworks by default, JQuery will be easier to plug in, and the Rails helpers that simply add data attributes to your DOM elements can be used to achieve all sorts of presentation behavior.&lt;/p&gt;

&lt;p&gt;Regardless of that, the closer you are to your Javascript, the better you'll understand how the pieces play together and the more control you'll have over the app's client side behavior.&lt;/p&gt;

&lt;h5&gt;Resources&lt;/h5&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.railsenvy.com/2008/1/3/unobtrusive-javascript"&gt;Unobstrusive Javascript presentation&lt;/a&gt; by Jason Seifer.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://railscasts.com/episodes/136-jquery"&gt;JQuery Railscast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://ejohn.org/blog/html-5-data-attributes/"&gt;HTML 5 data attributes&lt;/a&gt;, an explanation by John Resig.&lt;/li&gt;
&lt;/ul&gt;

&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/TK47j4Op3_U" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/08/07/sortable-lists-with-jquery-in-rails/</feedburner:origLink></entry>
  
  <entry>
    <title>PostgreSQL, Rails, and why you should care</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/qFJoKMI4F04/" />
    <updated>2009-08-03T16:59:46+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/08/03/postgresql-rails-and-why-you-should-care</id>
    <content type="html">&lt;p&gt;MySQL is the most popular RDBMS used to back Ruby on Rails applications. However, there are many reasons to try out PostgreSQL. It offers performance, efficiency, feature set, configurability, and seamless integration in your Rails projects.&lt;/p&gt;

&lt;h3&gt;PostgreSQL Features&lt;/h3&gt;

&lt;p&gt;PostgreSQL supports all of the features you would expect from an open source RDMS, including many that are found in commercial databases (Oracle, DB2, SQL Server) such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The basics: &lt;a href="http://www.postgresql.org/docs/8.4/static/sql-createview.html"&gt;views&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/8.4/static/triggers.html"&gt;triggers&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/8.4/static/indexes.html"&gt;indexes&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/8.4/static/ddl-constraints.html#DDL-CONSTRAINTS-FK"&gt;foreign keys&lt;/a&gt;, ACIDity, &lt;a href="http://www.postgresql.org/docs/8.4/static/transaction-iso.html"&gt;transactions&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/8.4/static/geqo-pg-intro.html"&gt;query optimization&lt;/a&gt;, comprehensive SQL support and &lt;a href="http://www.postgresql.org/docs/8.4/static/datatype.html"&gt;data types&lt;/a&gt;, &lt;a href="http://www.postgresql.org/docs/current/static/routine-vacuuming.html"&gt;autovacuum&lt;/a&gt; (keeps your table statistics up to date).&lt;/li&gt;
&lt;li&gt;The not so basics: Features that may not be seen on other DBMSes include reverse, partial and expression indexes, table partitioning, table inheritance, cursors, data domains, user-defined operators, arrays and regular expressions.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.postgresql.org/docs/8.4/static/xplang.html"&gt;Procedural Languages&lt;/a&gt;: analogous to Oracle's PL/SQL or SQL Server's T/SQL, PostgreSQL supports internal procedural languages for when you need to get down and dirty with the data. Additionally, it supports a wide range of languages &lt;a href="http://raa.ruby-lang.org/project/pl-ruby/"&gt;including &lt;em&gt;Ruby&lt;/em&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.postgresql.org/docs/8.4/static/rules.html"&gt;Rules&lt;/a&gt;, which pretty much allow you to rewrite an incoming query. A typical use of Rules is to implement updatable views.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.postgresql.org/docs/current/static/mvcc-intro.html"&gt;Multi-Version Concurrency Control&lt;/a&gt;: MVCC is how PostgreSQL (and other DBMSes) deal with concurrency and table locking. In practical terms, it allows for database reads while the data is being writen.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.postgresql.org/docs/8.4/static/wal-intro.html"&gt;Write-Ahead-Log&lt;/a&gt;: the WAL is the mechanism by which PostgreSQL writes transactions to the log before they are written to the database. This increases reliability in the unlikely event of a database crash, as there will be a transaction log by which to rebuild the database's state. PostgreSQL includes many configuration parameters to &lt;a href="http://www.postgresql.org/docs/8.4/static/wal-configuration.html"&gt;tweak the behavior of the WAL&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;PostgreSQL scales up by efficiently using multi-core servers. It also sport an &lt;a href="http://www.postgresql.org/docs/8.3/static/libpq-async.html"&gt;asynchronous processing API&lt;/a&gt;. Subselects are fast, you can refer to tmp tables more than once in a query and it can use more than one index per query, making it suitable for data warehousing applications as well.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.postgresql.org/docs/8.4/static/tsearch2.html"&gt;tsearch2&lt;/a&gt;, which is PostgreSQL's highly efficient full text search component. If you are committed to PostgreSQL, this is a very high performant search engine for PostgreSQL (as an alternative to &lt;a href="http://lucene.apache.org/solr/"&gt;solr&lt;/a&gt; or &lt;a href="http://www.sphinxsearch.com/"&gt;sphinx&lt;/a&gt;, for instance), with the added benefit that you're not running a separate daemon or search service.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://postgis.refractions.net/"&gt;PostGIS&lt;/a&gt; for geospacial objects.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://pgcluster.projects.postgresql.org/"&gt;There&lt;/a&gt; &lt;a href="http://slony1.projects.postgresql.org/"&gt;are&lt;/a&gt; &lt;a href="http://sourceforge.net/projects/dbbalancer"&gt;many&lt;/a&gt; &lt;a href="http://pgpool.projects.postgresql.org/"&gt;replication&lt;/a&gt; &lt;a href="http://pg-comparator.projects.postgresql.org/"&gt;options&lt;/a&gt;, although non of them are built into the core. This will &lt;a href="http://archives.postgresql.org/pgsql-hackers/2008-05/msg00913.php"&gt;change very soon&lt;/a&gt;, though.&lt;/li&gt;
&lt;li&gt;You can tweak its brains out: open up postgresql.conf, and you'll find many configuration options that can be tweaked to your application load and server capabilities. If you're like me, this is lots of fun. I will say, however, that it will take time to understand many of the options and how they affect each other.&lt;/li&gt;
&lt;li&gt;Excellent &lt;a href="http://www.postgresql.org/docs/8.4/interactive/index.html"&gt;documentation&lt;/a&gt;, which not only goes through the basics of setting up and using PostgreSQL, but really gets into the details of the inner workings of the system. This is an invaluable resource, not only for day-to-day development but also for tweaking the database's configuration files.&lt;/li&gt;
&lt;li&gt;Much more in the &lt;a href="http://www.postgresql.org/docs/8.4/interactive/contrib.html"&gt;contrib&lt;/a&gt; packages.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;PostgreSQL License&lt;/h3&gt;

&lt;p&gt;PostgreSQL is &lt;a href="http://www.postgresql.org/about/licence"&gt;released under a BSD License&lt;/a&gt;, and as such it is truly an Open Source Project. There are many contributors to the project, both individuals who donate their time as well as companies that improve the codebase (such as &lt;a href="http://www.enterprisedb.com/"&gt;EnterpriseDB&lt;/a&gt; and &lt;a href="http://www.commandprompt.com/"&gt;Command Prompt&lt;/a&gt;). If you are looking for the PostgreSQL gatekeeper, you'll be chasing your tail: There's no such thing. It is truly "Free Software".&lt;/p&gt;

&lt;h3&gt;So, what is it? MySQL or PostgreSQL?&lt;/h3&gt;

&lt;p&gt;Historically, MySQL was built with performance in mind, whereas PostgreSQL was built with features in mind. The ease of use of MySQL earned it the popularity seen on most open source web application developers. Since then, however, two things have happened: PostgreSQL has become much faster and efficient, and MySQL has become more feature-rich. In my mind, the performance or feature argument is no longer valid for web applications. Both databases have their strengths and weaknesses and as you work out an expertise on either one of them it will become a moot point. Some of the lacking MySQL features are of interest only to DBAs, not web app developers, although this may be a consideration for larger shops and deployments.&lt;/p&gt;

&lt;p&gt;One of the major reasons for trying out PostgreSQL, regardless of it's feature set, is it's &lt;em&gt;license and community&lt;/em&gt;. This can't be more true these days, when MySQL AB was consumed by Sun Microsystems, which in turn recently got acquired by Oracle. While I doubt that the product itself may die off, the fact that the copyright to the code, and the direction of the database system itself may and will be dictated by a company like Oracle is a deal breaker for me. At this point it is hard to tell if this is good or bad for MySQL and the community around it, but it definitely shows turmoil in the MySQL ecosystem. Note that I am not implying that Oracle sees MySQL as a threat to Oracle DB. In fact, I believe that MySQL satisfies a completely different niche.&lt;/p&gt;

&lt;p&gt;On the other hand, PostgreSQL is a community effort along the same lines as the Ruby and Rails communities. This makes it a more attractive option as the direction of the project is community driven, immune to corporate politics and revenue motives.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/qFJoKMI4F04" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/08/03/postgresql-rails-and-why-you-should-care/</feedburner:origLink></entry>
  
  <entry>
    <title>Attach non image files in Rails with paperclip</title>
    <link href="http://feedproxy.google.com/~r/practiceovertheory/~3/2mVvWpJaPyw/" />
    <updated>2009-05-19T22:40:10+00:00</updated>
    <id>http://practiceovertheory.com/blog/2009/05/19/attach-non-image-files-in-rails-with-paperclip</id>
    <content type="html">&lt;p&gt;Paperclip has pretty much become the standard when it comes to attaching files to models in Rails. It has a very easy to use API, allows the user to &lt;a href="http://dev.thoughtbot.com/paperclip/classes/Paperclip/Processor.html"&gt;create her own post-processing code&lt;/a&gt; (such as OCR or others), and provides callbacks for before and after post-processing.This post does not cover getting started with paperclip. There are plenty of other posts that cover that. The intent is to get you up and running on using paperclip to attach non-image files.&lt;/p&gt;

&lt;p&gt;Out of the box, the default post processor invoked upon upload is the &lt;a href="http://dev.thoughtbot.com/paperclip/classes/Paperclip/Thumbnail.html"&gt;Paperclip::Thumbnail&lt;/a&gt; processor. This processor creates thumbnails of an image based on the styles hash passed to the &lt;code&gt;has_attached_file&lt;/code&gt; method. If you want to upload word documents, excel files, and other non-image data, the Thumbnail processor will fail, and the attachment will not succeed. This processor does not check if the file itself is an image, and tries to call ImageMagick's identify command on the file anyways.&lt;/p&gt;

&lt;p&gt;Paperclip makes solving this extremely simple: prevent the post processing from happening when the file is not an image. Just like on &lt;code&gt;ActiveRecord&lt;/code&gt; callbacks, you can return false on paperclip's &lt;code class="inline_code"&gt;before_post_process&lt;/code&gt; callback to avoid the processing from happening in the first place.&lt;/p&gt;

&lt;p&gt;One possible solution is to put the following in whatever model you're using paperclip on:&lt;/p&gt;

&lt;div&gt;&lt;figure role=code&gt; &lt;div class="highlight"&gt;&lt;table cellpadding="0" cellspacing="0"&gt;&lt;tr&gt;&lt;td class="gutter"&gt;&lt;pre class="line-numbers"&gt;&lt;span class='line'&gt;1&lt;/span&gt;
&lt;span class='line'&gt;2&lt;/span&gt;
&lt;span class='line'&gt;3&lt;/span&gt;
&lt;span class='line'&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class='code' width='100%'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;&lt;div class='line'&gt;&lt;span class="n"&gt;before_post_process&lt;/span&gt; &lt;span class="ss"&gt;:image?&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;image?&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;  &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;data_content_type&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/^image.*/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;nil?&lt;/span&gt;
&lt;/div&gt;&lt;div class='line'&gt;&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/div&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;&lt;/div&gt;


&lt;p&gt;In this case, we've created an image? method which returns true if the content type starts with the string image (as in 'image/png', 'image/jpeg', etc). What's neat about this is that this same method can be used in your views to either render an &lt;code&gt;image_tag&lt;/code&gt;, or something else such as an icon or the file's name, depending on whether the file is an image.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/practiceovertheory/~4/2mVvWpJaPyw" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://practiceovertheory.com/blog/2009/05/19/attach-non-image-files-in-rails-with-paperclip/</feedburner:origLink></entry>
  
</feed>

