<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>rpheath.com</title>
    <link>http://rpheath.com/</link>
    <description>The personal blog of Ryan Heath.</description>
    <language>en-us</language>
    <item>
      <author>Ryan Heath | filed under Programming</author>
      <title>Rails' StringInquirer</title>
      <description>&lt;p&gt;A &lt;a href="http://github.com/rails/rails/commit/8afa725f4b98a6e0ceee4792e8ebaebb6189e5f6"&gt;recent commit to Rails&lt;/a&gt;. When the last method of a method chain ends with a question mark, the entire chain reads like a question.&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Rails&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;env&lt;/span&gt; &lt;span class="punct"&gt;==&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;production&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Rails&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;env&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;production?&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The latter is &lt;em&gt;much&lt;/em&gt; better. I love these smart little additions. Any string wrapped up in a &lt;a href="http://github.com/rails/rails/tree/master/activesupport/lib/active_support/string_inquirer.rb"&gt;StringInquirer&lt;/a&gt; has this functionality.&lt;/p&gt;</description>
      <pubDate>Fri, 27 Jun 2008 11:27:05 -0400</pubDate>
      <link>http://rpheath.com/posts/327-rails-stringinquirer</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Programming</author>
      <title>Rails plugin: has_params</title>
      <description>&lt;p&gt;This is yet another edition of pointless programming. Ready. Set. Go!&lt;/p&gt;


	&lt;p&gt;To me, checking if parameters exist via the &lt;code&gt;params&lt;/code&gt; hash is ugly. My fingers start to quiver when I type &lt;code&gt;params[:whatever]&lt;/code&gt; more than once on the same line. Sometimes I&amp;#8217;ll add a private method to simply check if parameters exist. It just reads better, &lt;acronym title="In My Humble Opinion"&gt;IMHO&lt;/acronym&gt;.&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;using_open_id?&lt;/span&gt;
  &lt;span class="comment"&gt;# process OpenID authentication&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;

&lt;span class="ident"&gt;private&lt;/span&gt;
  &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;using_open_id?&lt;/span&gt;
    &lt;span class="punct"&gt;!&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:openid_url&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;blank?&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Maybe you&amp;#8217;ve done something similar, maybe you haven&amp;#8217;t. Being the pointless programmer that I am, I wrote a plugin to take care of this for &lt;em&gt;any and all&lt;/em&gt; parameters. I called it, has_params. You can find it on &lt;a href="http://github.com/rpheath/has_params/tree/master"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;Example(s)&lt;/h3&gt;


	&lt;p&gt;I suppose there&amp;#8217;s no harm in duplicating the &lt;span class="caps"&gt;README&lt;/span&gt;, huh? Anyway, here&amp;#8217;s how it works:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="comment"&gt;# the &amp;quot;old&amp;quot; way&lt;/span&gt;
&lt;span class="constant"&gt;Project&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;].&lt;/span&gt;&lt;span class="ident"&gt;blank?&lt;/span&gt;
&lt;span class="constant"&gt;Project&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;

&lt;span class="comment"&gt;# the &amp;quot;has_params&amp;quot; way&lt;/span&gt;
&lt;span class="constant"&gt;Project&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="ident"&gt;blank_project_params?&lt;/span&gt;
&lt;span class="constant"&gt;Project&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;has_project_params?&lt;/span&gt;
&lt;span class="constant"&gt;Project&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;params&lt;/span&gt;&lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:project&lt;/span&gt;&lt;span class="punct"&gt;])&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;project_params?&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;You basically just plug the key that you&amp;#8217;d otherwise use for &lt;code&gt;params&lt;/code&gt; into the standard &amp;#8220;has_params&amp;#8221; format. So, for &lt;code&gt;params[xxx]&lt;/code&gt; you&amp;#8217;d have one of the following to choose from:&lt;/p&gt;


	&lt;ul&gt;
	&lt;li&gt;&lt;code&gt;blank_xxx_params?&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;has_xxx_params?&lt;/code&gt;&lt;/li&gt;
		&lt;li&gt;&lt;code&gt;xxx_params?&lt;/code&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;Personally, I think it cleans up controller code a little. Brick-by-brick my friends, brick-by-brick.&lt;/p&gt;


	&lt;h3&gt;Gotcha!&lt;/h3&gt;


	&lt;p&gt;If you&amp;#8217;re using &lt;code&gt;method_missing&lt;/code&gt; in your controller(s), make sure you call &lt;code&gt;super&lt;/code&gt; at some point. This plugin also uses &lt;code&gt;method_missing&lt;/code&gt; and at a higher point in the inheritance chain (unless you&amp;#8217;re also mixing into &lt;code&gt;ActionController::Base&lt;/code&gt;), so if &lt;code&gt;super&lt;/code&gt; isn&amp;#8217;t called, Rails will be perfectly satisfied with &lt;em&gt;your&lt;/em&gt; version of &lt;code&gt;method_missing&lt;/code&gt;, ignoring the has_params&amp;#8217; version. At least, I&amp;#8217;m pretty sure that&amp;#8217;s what would happen. Consider yourself warned.&lt;/p&gt;


	&lt;h3&gt;Installation&lt;/h3&gt;


	&lt;p&gt;I can only imagine how excited you are to install this sucker. Here&amp;#8217;s how:&lt;/p&gt;


&lt;pre&gt;
&amp;gt;&amp;gt; cd project_root/vendor/plugins
&amp;gt;&amp;gt; git clone git://github.com/rpheath/has_params.git 
&lt;/pre&gt;

	&lt;p&gt;And that concludes this edition of pointless programming. I hope you&amp;#8217;ve enjoyed it :-)&lt;/p&gt;</description>
      <pubDate>Wed, 18 Jun 2008 18:06:13 -0400</pubDate>
      <link>http://rpheath.com/posts/326-rails-plugin-has-params</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Programming</author>
      <title>Rails plugin: EasySearch</title>
      <description>&lt;p&gt;Have you ever written a plugin or a piece of code that was more fun to write than it was actually worth? I seem to do that a lot&amp;#8212;I enjoy experimenting with Ruby. Recently, I needed to search &lt;code&gt;ActiveRecord&lt;/code&gt; models individually, and was in the mood to write a simple &lt;span class="caps"&gt;DSL&lt;/span&gt;. It&amp;#8217;s now in plugin form, called EasySearch, and can be found on &lt;a href="http://github.com/rpheath/easy_search/tree/master"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;


	&lt;p&gt;It doesn&amp;#8217;t support joins or shared indexes or anything else you might come to expect from a search plugin. I&amp;#8217;m posting about it not because I think you should use it, but because I think it&amp;#8217;s a pretty cool &lt;span class="caps"&gt;API&lt;/span&gt; for searching.&lt;/p&gt;


	&lt;p&gt;So, install the plugin and do something like this:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Search&lt;/span&gt;
  &lt;span class="ident"&gt;include&lt;/span&gt; &lt;span class="constant"&gt;RPH&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;EasySearch&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;(I originally had a nice &lt;code&gt;acts_as_easy_search&lt;/code&gt; class method that hooked up the behavior, but I didn&amp;#8217;t feel right about mixing that into &lt;code&gt;Object&lt;/code&gt;. I wanted this plugin to work without the need of an &lt;code&gt;ActiveRecord&lt;/code&gt; superclass. Plus, AR would then be expecting a corresponding table in the database, which is another unnecessary need. So, manual inclusion is the answer until I come to terms with a better alternative. Continuing&amp;#8230;)&lt;/p&gt;


	&lt;p&gt;The &lt;code&gt;Search&lt;/code&gt; class now has the means to easily search any &lt;code&gt;ActiveRecord&lt;/code&gt; model within an application. Let&amp;#8217;s say I want to find all of the users who mention &amp;#8216;ruby&amp;#8217;. Let&amp;#8217;s reword that: search users with the term &amp;#8216;ruby&amp;#8217;.&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Search&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;users&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;ruby&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; [&amp;lt;#User ...&amp;gt;, &amp;lt;#User ...&amp;gt;, ...]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Makes sense, huh?&lt;/p&gt;


	&lt;p&gt;I have a confession to make: I lied about only having to include the module. Before anything will actually work, I&amp;#8217;ll need to tell &lt;code&gt;EasySearch&lt;/code&gt; about the tables I want to &lt;em&gt;easily search&lt;/em&gt;.&lt;/p&gt;


	&lt;h2&gt;EasySearch Configuration&lt;/h2&gt;


	&lt;p&gt;For any generic search plugin to work, there needs to be a way to specify which database columns the search terms should be matched against. Here&amp;#8217;s an example of how it works:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="comment"&gt;# in Rails 2.0+ you could put this in &lt;/span&gt;
&lt;span class="comment"&gt;# config/initializers/easy_search_setup.rb&lt;/span&gt;
&lt;span class="comment"&gt;# (otherwise just use config/environment.rb)&lt;/span&gt;

&lt;span class="constant"&gt;RPH&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;EasySearch&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Setup&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;config&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;setup_tables&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;users&lt;/span&gt;    &lt;span class="symbol"&gt;:first_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:last_name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:email&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:bio&lt;/span&gt;
    &lt;span class="ident"&gt;projects&lt;/span&gt; &lt;span class="symbol"&gt;:title&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:description&lt;/span&gt;
    &lt;span class="ident"&gt;groups&lt;/span&gt;   &lt;span class="symbol"&gt;:name&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;There, that&amp;#8217;s it (for real this time).&lt;/p&gt;


	&lt;p&gt;If you notice, it looks like there are &amp;#8220;users&amp;#8221;, &amp;#8220;projects&amp;#8221;, and &amp;#8220;groups&amp;#8221; methods that are called from within the block. And actually, that&amp;#8217;s correct. The only difference is those methods don&amp;#8217;t exist &lt;em&gt;until&lt;/em&gt; they&amp;#8217;re called, and even then they don&amp;#8217;t &amp;#8220;exist&amp;#8221; (which is kind of weird, I know, but incredibly awesome nonetheless). Don&amp;#8217;t worry about &lt;em&gt;how&lt;/em&gt; it works (&lt;a href="http://github.com/rpheath/easy_search/tree/master/lib/easy_search/setup.rb"&gt;read through the code&lt;/a&gt; if you&amp;#8217;re interested), just follow the pattern (use the table names instead of the model names).&lt;/p&gt;


	&lt;p&gt;After this one-time configuration is done, I can do things like:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Search&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;users&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;ryan&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; [&amp;lt;#User ...&amp;gt;]&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Search&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;projects&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;design&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; [&amp;lt;#Project ...&amp;gt;]&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;Search&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;groups&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;friends&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; [&amp;lt;#Group ...&amp;gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;If you try to search a model that hasn&amp;#8217;t been configured, &lt;code&gt;EasySearch&lt;/code&gt; will let you know. After all, how else would it know which columns to look in? It&amp;#8217;s not &lt;em&gt;that&lt;/em&gt; magical.&lt;/p&gt;


	&lt;p&gt;And getting a hold of the current table configuration is easy:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;RPH&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;EasySearch&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Setup&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;table_settings&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; {&amp;quot;users&amp;quot; =&amp;gt; [:first_name, :last_name, :email, :bio], &amp;quot;projects&amp;quot; =&amp;gt; ...}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;h2&gt;How it Works&lt;/h2&gt;


	&lt;p&gt;Really, all &lt;code&gt;EasySearch&lt;/code&gt; is doing is building a &lt;span class="caps"&gt;WHERE&lt;/span&gt; clause and using conventions to pass that on to the appropriate finder. So &lt;code&gt;Search.users&lt;/code&gt; is really doing &lt;code&gt;User.find&lt;/code&gt; with a custom conditions clause.&lt;/p&gt;


	&lt;p&gt;Let&amp;#8217;s say I want to search my &lt;code&gt;User&lt;/code&gt; model for &amp;#8220;ryan heath ruby&amp;#8221;.&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="constant"&gt;Search&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;users&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;ryan heath ruby&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This would not only compare &amp;#8220;ryan heath ruby&amp;#8221; with each of the specified columns (you know, from the configuration), but it&amp;#8217;d compare &amp;#8220;ryan&amp;#8221;, &amp;#8220;heath&amp;#8221;, and &amp;#8220;ruby&amp;#8221; individually against each of the specified columns, providing more accurate results.&lt;/p&gt;


	&lt;p&gt;This, however, is an incredible performance limitation and is why this plugin is &lt;em&gt;not&lt;/em&gt; meant for those gigantic applications with tons and tons of database records. It builds a potentially large &lt;span class="caps"&gt;WHERE&lt;/span&gt; clause using &lt;span class="caps"&gt;LIKE&lt;/span&gt;, which is quite slow in the computer world. For those large applications, it&amp;#8217;s far better to use a &lt;a href="http://en.wikipedia.org/wiki/Full_text_search"&gt;full text&lt;/a&gt; solution. But again, this is all (more-or-less) for fun with little profit. I had a need to search individual models separately in a small application, so there you go. I can always go back and rework the back-end to operate differently/more efficient.&lt;/p&gt;


	&lt;p&gt;Oh, and since a rather large &lt;span class="caps"&gt;WHERE&lt;/span&gt; clause is being constructed, checking each term individually, I want to ignore meaningless words to avoid the extra overhead. For example, let&amp;#8217;s say I tweak my search to be:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="constant"&gt;Search&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;users&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;with&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;ryan heath is a ruby&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;&lt;code&gt;EasySearch&lt;/code&gt; would still only search &amp;#8220;ryan&amp;#8221;, &amp;#8220;heath&amp;#8221;, and &amp;#8220;ruby&amp;#8221;, ignoring the &amp;#8220;is&amp;#8221; and &amp;#8220;a&amp;#8221; (because they&amp;#8217;re &lt;em&gt;dull&lt;/em&gt;). You can easily see what keywords are considered &amp;#8220;dull&amp;#8221; by doing:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;RPH&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;EasySearch&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Setup&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;dull_keywords&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; ['the', 'a', ...]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now I know what you&amp;#8217;re thinking, &amp;#8220;Who gets to decide what keywords are &lt;em&gt;dull&lt;/em&gt; keywords?&amp;#8221; The programmer, of course! By default, &lt;code&gt;EasySearch&lt;/code&gt; has a predefined list of keywords that it thinks are meaningless. But you can add to that list quite easily. Using the same &lt;code&gt;Setup.config&lt;/code&gt; block:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="constant"&gt;RPH&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;EasySearch&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Setup&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;config&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;setup_tables&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="comment"&gt;# ...&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="ident"&gt;strip_keywords&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;other&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;you&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;do&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;not&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;want&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;to&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;search&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;That will append those keywords to the default list (and will only count a dull keyword once, so don&amp;#8217;t worry about duplication). If I wanted to ignore the default list completely (instead of appending to it), I&amp;#8217;d just have to pass &lt;code&gt;true&lt;/code&gt; to the &lt;code&gt;strip_keywords&lt;/code&gt; method, like so:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;strip_keywords&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="punct"&gt;['&lt;/span&gt;&lt;span class="string"&gt;other&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;words&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;you&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;do&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;not&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;want&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;to&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;search&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So that&amp;#8217;s about it. It&amp;#8217;s a fun plugin to play with, and like I said, it was more fun to write than it&amp;#8217;s probably worth. But honestly, I think this sort of experimentation is nothing but good for programmer experience. And besides, every now and then, an &amp;#8220;experiment&amp;#8221; turns into something awesome (see &lt;a href="http://errtheblog.com/posts/63-full-of-ambition"&gt;Ambition&lt;/a&gt; for a prime example).&lt;/p&gt;</description>
      <pubDate>Tue, 20 May 2008 23:04:42 -0400</pubDate>
      <link>http://rpheath.com/posts/325-rails-plugin-easysearch</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Programming</author>
      <title>Ruby conditions</title>
      <description>&lt;p&gt;Often the conditions of an if statement are dependent on more than one thing, and sometimes it&amp;#8217;s of the form, &amp;#8220;if A is true and B is false&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;Avoiding the details, let&amp;#8217;s say I wanted to do something like this:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;cache!&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;needs_cached?&lt;/span&gt; &lt;span class="punct"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="punct"&gt;!&lt;/span&gt;&lt;span class="constant"&gt;API&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;local?&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Essentially that&amp;#8217;s saying &amp;#8220;cache the user if the user needs cached (A is true) and the &lt;span class="caps"&gt;API&lt;/span&gt; is &lt;em&gt;&lt;span class="caps"&gt;NOT&lt;/span&gt;&lt;/em&gt; a local request (B is false). The &lt;code&gt;&amp;#38;&amp;#38; !&lt;/code&gt; is fine and all, and it&amp;#8217;s actually quite readable to most programmers, but were you aware that you could do this?&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;&lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;cache!&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;needs_cached?&lt;/span&gt; &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="constant"&gt;API&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;local?&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Maybe I&amp;#8217;m flying solo on this one, but I wasn&amp;#8217;t aware that you could use &lt;code&gt;if&lt;/code&gt; and &lt;code&gt;unless&lt;/code&gt; to chain conditions together. And I&amp;#8217;m sure this is one of those Ruby moments where I just need to take a step back and find the right perspective. Sometimes things aren&amp;#8217;t always what they seem (like how &lt;code&gt;1+3&lt;/code&gt; is actually &lt;code&gt;1.+(3)&lt;/code&gt;).&lt;/p&gt;</description>
      <pubDate>Mon, 05 May 2008 22:58:27 -0400</pubDate>
      <link>http://rpheath.com/posts/324-ruby-conditions</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Programming</author>
      <title>Railscasts Contest: 5 Rails Tips</title>
      <description>&lt;p&gt;There&amp;#8217;s a &lt;a href="http://railscasts.com/contest"&gt;contest on Railscasts&lt;/a&gt; that has me feeling compelled to participate. So I am. To enter, the contest requires 5 tips concerning Rails, all in one post. So, this post will more than likely be one of the longest I&amp;#8217;ve written in a while, but hopefully it will serve as a good resource/reference for other Rails developers. Without further ado, here are my five tips:&lt;/p&gt;


	&lt;p class="alert"&gt;&lt;strong&gt;Note:&lt;/strong&gt; I haven&amp;#8217;t wrapped my View code examples in the &lt;span class="caps"&gt;ERB&lt;/span&gt; &lt;code&gt;&amp;lt;%= -%&amp;gt;&lt;/code&gt; tags, as it currently makes the syntax highlighting terribly hard to read. I just wanted to make new comers aware until I can get this issue fixed.&lt;/p&gt;


	&lt;h2&gt;Tip 1: Navigation Helper Plugin&lt;/h2&gt;


	&lt;p&gt;Nearly &lt;em&gt;every&lt;/em&gt; web application has some sort of navigation. Albeit tabs, menus, plain links, whatever, there needs to be a way to click through the application. And more often than not, keeping track of the current section/tab is a desired feature. Well, I wrote a Rails plugin called &lt;a href="http://github.com/rpheath/navigation_helper/tree/master"&gt;navigation_helper&lt;/a&gt; to assist with these needs.&lt;/p&gt;


	&lt;h3&gt;Basic Usage&lt;/h3&gt;


	&lt;p&gt;Once installed, here&amp;#8217;s how the plugin works:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="comment"&gt;# somewhere in your view (typically your layout)&lt;/span&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:contact&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;

&lt;span class="comment"&gt;# HTML output:&lt;/span&gt;
&lt;span class="comment"&gt;#   &amp;lt;ul class=&amp;quot;nav_bar&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li class=&amp;quot;current&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/home&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/contact&amp;quot;&amp;gt;Contact&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#   &amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;You pass an array of symbols representing the sections that the links will navigate to. The link text will be a capitalized version of the symbol passed in. So &lt;code&gt;:home&lt;/code&gt; becomes &amp;#8216;Home&amp;#8217;; &lt;code&gt;:contact_me&lt;/code&gt; becomes &amp;#8216;Contact Me&amp;#8217;; and so on.&lt;/p&gt;


	&lt;p&gt;An important thing to be aware of: the helper will be expecting a named route mapped to the section passed in the array. For instance, for the &lt;code&gt;:home&lt;/code&gt; section, the navigation helper will use &lt;code&gt;home_path&lt;/code&gt; to build the link. And for &lt;code&gt;:about&lt;/code&gt;, it will look for &lt;code&gt;about_path&lt;/code&gt;. And so on. You need to make sure those routes are defined in your routes.rb file (it&amp;#8217;s good practice to use named routes, this plugin just enforces that practice).&lt;/p&gt;


	&lt;p&gt;And as you can see, the markup is &lt;em&gt;very&lt;/em&gt; extensible (in terms of &lt;span class="caps"&gt;CSS&lt;/span&gt;) with the use of an unordered list. The list item that holds the current section will get a &lt;span class="caps"&gt;CSS&lt;/span&gt; class of &amp;#8220;current&amp;#8221;. And the unordered list itself gets a &lt;span class="caps"&gt;CSS&lt;/span&gt; class rather than an ID, so that it can be used multiple times on the same page and not break your strict &lt;span class="caps"&gt;XHTML&lt;/span&gt; markup :-)&lt;/p&gt;


	&lt;h3&gt;Adding Subtitles&lt;/h3&gt;


	&lt;p&gt;Sometimes it&amp;#8217;s a nice touch to add subtitles to your navigation (see &lt;a href="http://portfolio.rpheath.com"&gt;my portfolio&lt;/a&gt; for example). This plugin has support for that. All you have to do is pass a string of the subtitle right after the section that the subtitle should be associated with. For example:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Start Here&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Learn More&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:contact&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Get In Touch&lt;/span&gt;&lt;span class="punct"&gt;']&lt;/span&gt;

&lt;span class="comment"&gt;# HTML output:&lt;/span&gt;
&lt;span class="comment"&gt;#  &amp;lt;ul class=&amp;quot;nav_bar&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;li class=&amp;quot;current&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#      &amp;lt;a href=&amp;quot;/home&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#      &amp;lt;span&amp;gt;Start Here&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#      &amp;lt;a href=&amp;quot;/about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#      &amp;lt;span&amp;gt;Learn More&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#      &amp;lt;a href=&amp;quot;/contact&amp;quot;&amp;gt;Contact&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#      &amp;lt;span&amp;gt;Get In Touch&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#  &amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;As you can see, the markup generated is clean and is ready for some &lt;span class="caps"&gt;CSS&lt;/span&gt; love. Now, what if you would rather those subtitles just be hover text on the link instead of full-blown &lt;code&gt;span&lt;/code&gt; elements? No problem, just let the navigation helper know with the &lt;code&gt;:hover_text =&amp;gt; true&lt;/code&gt; option:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Start Here&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Learn More&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:contact&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Get In Touch&lt;/span&gt;&lt;span class="punct"&gt;'],&lt;/span&gt; &lt;span class="symbol"&gt;:hover_text&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="constant"&gt;true&lt;/span&gt;

&lt;span class="comment"&gt;# HTML output:&lt;/span&gt;
&lt;span class="comment"&gt;#  &amp;lt;ul class=&amp;quot;nav_bar&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;li class=&amp;quot;current&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/home&amp;quot; title=&amp;quot;Start Here&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/about&amp;quot; title=&amp;quot;Learn More&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#    &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/contact&amp;quot; title=&amp;quot;Get In Touch&amp;quot;&amp;gt;Contact&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#  &amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The &lt;code&gt;span&lt;/code&gt; elements will transform into &lt;em&gt;title&lt;/em&gt; attributes on the links, so the text will only show up on hover.&lt;/p&gt;


	&lt;h3&gt;Authorized Sections&lt;/h3&gt;


	&lt;p&gt;Now, a definite need (for me at least) is to have certain tabs show up depending on some condition, such as a user being logged in. For instance, on this very site, the public sees &amp;#8216;Portfolio&amp;#8217;, &amp;#8216;Words&amp;#8217;, &amp;#8216;Archives&amp;#8217;, and &amp;#8216;About&amp;#8217; tabs. But if I&amp;#8217;m logged in, there&amp;#8217;s also an &amp;#8216;Admin&amp;#8217; tab, which allows me to access the area to post new entries, add categories, edit/delete comments, etc. But I only want that tab visible based on me being logged in. Well, I&amp;#8217;ve added support for that, too. Just specify which sections should be &amp;#8220;authorized&amp;#8221; sections, like so:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:reports&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:authorize&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:reports&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;

&lt;span class="comment"&gt;# HTML output:&lt;/span&gt;
&lt;span class="comment"&gt;#   &amp;lt;ul class=&amp;quot;nav_bar&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li class=&amp;quot;current&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/home&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li&amp;gt;&amp;lt;a href=&amp;quot;/about&amp;quot;&amp;gt;About&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li class=&amp;quot;authorized_nav_link&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/admin&amp;quot;&amp;gt;Admin&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#     &amp;lt;li class=&amp;quot;authorized_nav_link&amp;quot;&amp;gt;&amp;lt;a href=&amp;quot;/reports&amp;quot;&amp;gt;Reports&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;&lt;/span&gt;
&lt;span class="comment"&gt;#   &amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;By default, the link will be &amp;#8220;authorized&amp;#8221; by checking a &lt;code&gt;logged_in?&lt;/code&gt; method. If you don&amp;#8217;t have a &lt;code&gt;logged_in?&lt;/code&gt; method, or need some other means of authorization (such as checking if the current_user has the admin role), then you can specify which method you&amp;#8217;d like the navigation helper to check against by using the &lt;code&gt;:with&lt;/code&gt; option:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:reports&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:authorize&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:reports&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:with&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:administrator?&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now the plugin will only show the &amp;#8216;Admin&amp;#8217; and &amp;#8216;Reports&amp;#8217; tabs if the &lt;code&gt;administrator?&lt;/code&gt; method exists and returns true. (Note: if the authorization method doesn&amp;#8217;t exist, the helper won&amp;#8217;t crash, it will simply not show the authorized tabs)&lt;/p&gt;


	&lt;p&gt;Also notice how the admin links get a special &amp;#8220;authorized_nav_link&amp;#8221; &lt;span class="caps"&gt;CSS&lt;/span&gt; class. That&amp;#8217;s because sometimes you want your &amp;#8220;admin&amp;#8221; tabs to appear differently, and this gives you the power to do so. For instance, you may have your common tabs to the left, but your admin tabs floating to the right. And just to be clear, if an authorized link happens to be the current section, it will simply append the &lt;span class="caps"&gt;CSS&lt;/span&gt; classes (i.e. class=&amp;#8221;authorized_nav_link current&amp;#8221;).&lt;/p&gt;


	&lt;p&gt;I&amp;#8217;ll admit, the &amp;#8220;authorized_nav_link&amp;#8221; isn&amp;#8217;t the best &lt;span class="caps"&gt;CSS&lt;/span&gt; class name, but it&amp;#8217;s best to keep defaults such as that awkward so they don&amp;#8217;t interfere with your current &lt;span class="caps"&gt;CSS&lt;/span&gt; classes. However, you can pass another option to override that class, like so:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:contact&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:authorize&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:authorize_css&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;custom_css&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;There&amp;#8217;s one more thing to mention about authorized links. Let&amp;#8217;s say you&amp;#8217;re using this for an admin menu, where all of the links are to be &amp;#8220;authorized&amp;#8221;. Rather than list out all of the authorized links again, you can pass an &lt;code&gt;:all&lt;/code&gt; to the &lt;code&gt;:authorize&lt;/code&gt; option, like so:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:users&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:reports&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:logs&lt;/span&gt;&lt;span class="punct"&gt;],&lt;/span&gt; &lt;span class="symbol"&gt;:authorize&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:all&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now all tabs will be authorized. Pretty simple, huh?&lt;/p&gt;


	&lt;h3&gt;Setting Current Tab&lt;/h3&gt;


	&lt;p&gt;Up to this point, you may be wondering how the helper knows which tab/section is the &amp;#8220;current&amp;#8221; tab/section. Well, it&amp;#8217;s simple. By default the plugin uses the controller&#8217;s name to determine the current tab (or link or section) you&#8217;re on. But as we all know, that&amp;#8217;s not always feasible. Just because you have a &lt;code&gt;PublicController&lt;/code&gt; doesn&amp;#8217;t mean you want your link to be &amp;#8220;Public&amp;#8221; in the navigation menu. To fix that issue, you can specify the current tab for any controller by doing:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;PublicController&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ApplicationController&lt;/span&gt;
  &lt;span class="ident"&gt;current_tab&lt;/span&gt; &lt;span class="symbol"&gt;:home&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now something like this will work as intended:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;navigation&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="symbol"&gt;:home&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:about&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:contact&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The &lt;code&gt;PublicController&lt;/code&gt; will be seen as &lt;code&gt;:home&lt;/code&gt; to the navigation helper, and will choose the current tab accordingly. This is also very handy for namespaced controllers.&lt;/p&gt;


	&lt;h3&gt;Install via Git&lt;/h3&gt;


	&lt;p&gt;You can find this plugin on &lt;a href="http://github.com/rpheath/navigation_helper/tree/master"&gt;GitHub&lt;/a&gt; (and see the &lt;span class="caps"&gt;README&lt;/span&gt; for more/better examples), and can be installed by doing:&lt;/p&gt;


&lt;pre&gt;
$&amp;gt; cd path/to/your/rails/project/vendor/plugins
$&amp;gt; git clone git://github.com/rpheath/navigation_helper.git
&lt;/pre&gt;

	&lt;p&gt;You can download a &lt;a href="http://github.com/rpheath/navigation_helper/tarball/master"&gt;tarball&lt;/a&gt; if you don&amp;#8217;t have Git installed. And for completeness, here&amp;#8217;s the &lt;a href="http://rpheath.com/posts/309-rails-plugin-navigation-helper"&gt;original announcement&lt;/a&gt; of the navigation_helper plugin.&lt;/p&gt;


	&lt;h2&gt;Tip 2: Input &lt;span class="caps"&gt;CSS&lt;/span&gt; Plugin&lt;/h2&gt;


	&lt;p&gt;This next tip is more for &lt;em&gt;designers&lt;/em&gt; who work with Rails applications. As any designer would know, designing Forms can be somewhat of a pain, as there are many different types of &lt;span class="caps"&gt;INPUT&lt;/span&gt; tags (text boxes, password fields, submit buttons, file fields, etc). Obviously, you would not want to apply the same text box styling to a submit button, which means it requires extra work on &lt;em&gt;every&lt;/em&gt; form to make sure you&amp;#8217;re styling the correct &lt;span class="caps"&gt;INPUT&lt;/span&gt; tag.&lt;/p&gt;


	&lt;p&gt;Since I personally design &lt;em&gt;and&lt;/em&gt; develop Rails applications, I&amp;#8217;ve decided that it was time to attack this problem at its core. I wrote a plugin that will automatically add a &lt;span class="caps"&gt;CSS&lt;/span&gt; class based on the &amp;#8220;type&amp;#8221; attribute of any &lt;span class="caps"&gt;INPUT&lt;/span&gt; tag. And I&amp;#8217;ve called it, &lt;a href="http://github.com/rpheath/input_css/tree/master"&gt;input_css&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;How it Works&lt;/h3&gt;


	&lt;p&gt;Just install it. Then your standard form helpers will automatically have a class assigned to them. For example:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;text_field&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;
&lt;span class="comment"&gt;# =&amp;gt; &amp;lt;input type=&amp;quot;text&amp;quot; class=&amp;quot;text&amp;quot; name=&amp;quot;user[name]&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;/span&gt;

&lt;span class="ident"&gt;submit_tag&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;Create&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="symbol"&gt;:class&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;button&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="comment"&gt;# =&amp;gt; &amp;lt;input name=&amp;quot;commit&amp;quot; type=&amp;quot;submit&amp;quot; class=&amp;quot;button submit&amp;quot; value=&amp;quot;Create&amp;quot; /&amp;gt;&lt;/span&gt;

&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;check_box&lt;/span&gt; &lt;span class="symbol"&gt;:is_preview&lt;/span&gt;
&lt;span class="comment"&gt;# =&amp;gt; &amp;lt;input type=&amp;quot;checkbox&amp;quot; class=&amp;quot;checkbox&amp;quot; name=&amp;quot;article[is_preview]&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;So once the plugin is installed, the &lt;span class="caps"&gt;CSS&lt;/span&gt; to style your &lt;span class="caps"&gt;INPUT&lt;/span&gt; tags is simple:&lt;/p&gt;


&lt;pre&gt;
input.text     { ... }
input.submit   { ... }
input.file     { ... }
input.checkbox { ... }
input.radio    { ... }
...
&lt;/pre&gt;

	&lt;h3&gt;Install via Git&lt;/h3&gt;


	&lt;p&gt;This plugin can be found on &lt;a href="http://github.com/rpheath/input_css/tree/master"&gt;GitHub&lt;/a&gt;, and you can install it by doing:&lt;/p&gt;


&lt;pre&gt;
$&amp;gt; cd path/to/your/rails/project/vendor/plugins
$&amp;gt; git clone git://github.com/rpheath/input_css.git
&lt;/pre&gt;

	&lt;p&gt;Once installed, you&amp;#8217;re good to go. There&amp;#8217;s no setup, customization, etc. It taps directly into the existing Rails &lt;code&gt;tag&lt;/code&gt; helper, so all of your existing form elements will be updated! Now you have an easy and consistent way to style your forms.&lt;/p&gt;


	&lt;p&gt;Remember, if you don&amp;#8217;t have Git installed, you can download a &lt;a href="http://github.com/rpheath/input_css/tarball/master"&gt;tarball&lt;/a&gt;. Just put the source in your vendor/plugins directory.&lt;/p&gt;


	&lt;h2&gt;Tip 3: Acts As Lookup Plugin&lt;/h2&gt;


	&lt;p&gt;Maybe I&amp;#8217;m alone on this one, but do you find it a pain to deal with select (i.e. drop down) lists? If you&amp;#8217;re like me, I don&amp;#8217;t always remember the proper Rails syntax, or I want to add a default &lt;code&gt;nil&lt;/code&gt; option to the list, etc. They always just feel awkward to me. Here&amp;#8217;s a typical &lt;code&gt;select&lt;/code&gt; field you might find in one of my forms. It&amp;#8217;s simply a lookup to choose a category:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;select&lt;/span&gt; &lt;span class="symbol"&gt;:category_id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;[['&lt;/span&gt;&lt;span class="string"&gt;--&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="constant"&gt;nil&lt;/span&gt;&lt;span class="punct"&gt;]]&lt;/span&gt; &lt;span class="punct"&gt;+&lt;/span&gt; &lt;span class="constant"&gt;Category&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;find&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:all&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;collect&lt;/span&gt; &lt;span class="punct"&gt;{&lt;/span&gt; &lt;span class="punct"&gt;|&lt;/span&gt;&lt;span class="ident"&gt;m&lt;/span&gt;&lt;span class="punct"&gt;|&lt;/span&gt; &lt;span class="punct"&gt;[&lt;/span&gt;&lt;span class="ident"&gt;m&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;m&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;id&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt; &lt;span class="punct"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Yikes! That&amp;#8217;s sort of nasty to have that right in your views. At least, to me it is. So I wrote a plugin that assists with this &amp;#8220;lookup table&amp;#8221; issue. I&amp;#8217;ve so cleverly called it, &lt;a href="http://github.com/rpheath/acts_as_lookup/tree/master"&gt;acts_as_lookup&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;How it Works&lt;/h3&gt;


	&lt;p&gt;Once installed, you need to tell your model(s) that they should be acting as a lookup table. This is pretty straightforward, though:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Category&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;acts_as_lookup&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;You have to pass it the field/column name you want to show up in your drop down list. So in the example above, I want to be able to choose from a list of category names, hence the &lt;code&gt;:name&lt;/code&gt; parameter.&lt;/p&gt;


	&lt;p&gt;From there, you get two things: 1) a &lt;code&gt;lookup_for&lt;/code&gt; helper (used in your views) and 2) an &lt;code&gt;options_for_select&lt;/code&gt; class method for any model that is &amp;#8220;acting as a lookup table&amp;#8221;. Here&amp;#8217;s how you use both:&lt;/p&gt;


	&lt;h3&gt;Using options_for_select&lt;/h3&gt;


	&lt;p&gt;This is a clean way to get rid of that &lt;code&gt;collect&lt;/code&gt; nonsense I showed previously. So, redoing my above example using this plugin (and using &lt;code&gt;options_for_select&lt;/code&gt;), we have:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;select&lt;/span&gt; &lt;span class="symbol"&gt;:category_id&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="constant"&gt;Category&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;options_for_select&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;That&amp;#8217;s much cleaner. And it automatically adds the nil &amp;#8221;- -&amp;#8221; option as the default in your list. Arguably, though, there&amp;#8217;s even a better way: the &lt;code&gt;lookup_for&lt;/code&gt; helper.&lt;/p&gt;


	&lt;h3&gt;Using lookup_for&lt;/h3&gt;


	&lt;p&gt;The &lt;code&gt;lookup_for&lt;/code&gt; helper automatically generates the above, but it&amp;#8217;s a little cleaner:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;lookup_for&lt;/span&gt; &lt;span class="symbol"&gt;:product&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:category_id&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And if you&amp;#8217;re using a &lt;code&gt;FormBuilder&lt;/code&gt; (read: &amp;#8220;f.&amp;#8221; in front of your form helpers), it&amp;#8217;s even better. You only have to give it the foreign key to the lookup:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;f&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;lookup_for&lt;/span&gt; &lt;span class="symbol"&gt;:category_id&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Viola! The above example(s) will automagically generate something similar to (of course depending on the real data):&lt;/p&gt;


&lt;pre&gt;
&amp;lt;select&amp;gt;
  &amp;lt;option value="" selected="selected"&amp;gt;--&amp;lt;/option&amp;gt;
  &amp;lt;option value="1"&amp;gt;Appliances&amp;lt;/option&amp;gt;
  &amp;lt;option value="2"&amp;gt;Furniture&amp;lt;/option&amp;gt;
&amp;lt;/select&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;One thing to note, though: the foreign key must follow the traditional Rails convention for foreign keys. Meaning, for a &lt;code&gt;Category&lt;/code&gt;, you&#8217;d have &lt;code&gt;category_id&lt;/code&gt; foreign key reference; for a &lt;code&gt;Task&lt;/code&gt;, you&#8217;d have &lt;code&gt;task_id&lt;/code&gt; foreign key reference; and so on. The reason is because the plugin uses that foreign key to get at the Model in which it represents. But since that&#8217;s pretty standard to most Rails developers, I don&#8217;t think it bears too much constraint :-)&lt;/p&gt;


	&lt;h3&gt;Customization&lt;/h3&gt;


	&lt;p&gt;Now, you may be asking &amp;#8220;what if I don&amp;#8217;t want &amp;#8217;- -&amp;#8217; as my default option?&amp;#8221; or &amp;#8220;what if I don&amp;#8217;t want every category to show up?&amp;#8221; or &amp;#8220;what if I have a category order, other than alphabetical?&amp;#8221;. Not a problem. This plugin supports that sort of customization.&lt;/p&gt;


	&lt;h4&gt;Changing the Default Text&lt;/h4&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Category&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;acts_as_lookup&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:default_text&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;- Choose Category -&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; 
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And if you don&amp;#8217;t want a default &lt;code&gt;nil&lt;/code&gt; option at all, just set the &lt;code&gt;:default_text&lt;/code&gt; option to &lt;code&gt;:first&lt;/code&gt; (meaning, the first option of your data returned):&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Category&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;acts_as_lookup&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:default_text&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="symbol"&gt;:first&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Now there will be no default option in your drop down (in this example, it would be set to the first category of the collection instead).&lt;/p&gt;


	&lt;h4&gt;Limiting the Options&lt;/h4&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="comment"&gt;# only show categories from within the last 4 months&lt;/span&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Category&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;acts_as_lookup&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:conditions&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;[&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;created_at &amp;gt; ?&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;,&lt;/span&gt; &lt;span class="number"&gt;4&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;months&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;ago&lt;/span&gt;&lt;span class="punct"&gt;]&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;h4&gt;Displaying in a Different Order&lt;/h4&gt;


	&lt;p&gt;By default, the plugin will sort your options alphabetically, but you can change that, too:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;Category&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&lt;/span&gt; &lt;span class="constant"&gt;ActiveRecord&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Base&lt;/span&gt;
  &lt;span class="ident"&gt;acts_as_lookup&lt;/span&gt; &lt;span class="symbol"&gt;:name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:order&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;category_order ASC&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;And of course, you can combine the options and pass all three at once, I&amp;#8217;ve just shown them separately to emphasize each point.&lt;/p&gt;


	&lt;h3&gt;Install via Git&lt;/h3&gt;


	&lt;p&gt;You can find this plugin on &lt;a href="http://github.com/rpheath/acts_as_lookup/tree/master"&gt;GitHub&lt;/a&gt;, and it can be installed by doing:&lt;/p&gt;


&lt;pre&gt;
$&amp;gt; cd path/to/your/rails/project/vendor/plugins
$&amp;gt; git clone git://github.com/rpheath/acts_as_lookup.git
&lt;/pre&gt;

	&lt;p&gt;Remember, if you don&amp;#8217;t have Git installed, you can download a &lt;a href="http://github.com/rpheath/acts_as_lookup/tarball/master"&gt;tarball&lt;/a&gt;. Just put the source in your vendor/plugins directory.&lt;/p&gt;


	&lt;h2&gt;Tip 4: Automatic Fading Flash Messages&lt;/h2&gt;


	&lt;p&gt;This next tip is rather minor, but I think it adds a nice touch, and I seem to use it in all of my Rails applications. Basically, the idea is to show a &lt;code&gt;flash&lt;/code&gt; message for a predetermined amount of time, then slowly fade the message out. (I personally think it&amp;#8217;s tacky to leave it there, waiting on the user to navigate away from that area)&lt;/p&gt;


	&lt;p&gt;So, using &lt;a href="http://railscasts.com/episodes/18"&gt;a tip from a prior Railscast&lt;/a&gt;, we put this somewhere in our layout:&lt;/p&gt;


&lt;pre&gt;
&amp;lt;% flash.each do |key, msg| -%&amp;gt;
  &amp;lt;%= content_tag :p, msg, :id =&amp;gt; key -%&amp;gt;
&amp;lt;% end -%&amp;gt;
&lt;/pre&gt;

	&lt;p&gt;This will create a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag with an id of the flash type. Meaning, &lt;code&gt;flash[:notice] = '...'&lt;/code&gt; will give &lt;code&gt;&amp;lt;p id="notice"&amp;gt;...&amp;lt;/p&amp;gt;&lt;/code&gt; and &lt;code&gt;flash[:error] = '...'&lt;/code&gt; will give &lt;code&gt;&amp;lt;p id="error"&amp;gt;...&amp;lt;/p&amp;gt;&lt;/code&gt; and so on. Now, what we want to do is fade this &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element out. We&amp;#8217;ll use JavaScript to do this, and we&amp;#8217;ll want to put that JavaScript in public/javascripts/application.js of our main Rails project root.&lt;/p&gt;


	&lt;h3&gt;Fading Messages using jQuery&lt;/h3&gt;


&lt;pre&gt;
$(document).ready(function() {
  setTimeout(hideFlashMessages, 10000);
});

function hideFlashMessages() {
  $('p#notice, p#warning, p#error').fadeOut(5000)
}
&lt;/pre&gt;

	&lt;h3&gt;Fading Messages using Prototype/Scriptaculous&lt;/h3&gt;


&lt;pre&gt;
document.observe("dom:loaded", function() {
  setTimeout(hideFlashMessages, 10000);
});

function hideFlashMessages() {
  $$('p#notice, p#warning, p#error').each(function(e) { 
    if (e) Effect.Fade(e, { duration: 5.0 });
  });
}
&lt;/pre&gt;

	&lt;p&gt;(Note: the above examples were based on jQuery 1.2.3 and Prototype 1.6)&lt;/p&gt;


	&lt;p&gt;The above functions will allow the message to be shown for 10 seconds (10000 milliseconds) in full, then begin to fade the message out over a 5 second duration. Of course, just change the values to fit your needs/desires.&lt;/p&gt;


	&lt;h2&gt;Tip 5: Interfacing with &lt;span class="caps"&gt;SOAP&lt;/span&gt; Web Services&lt;/h2&gt;


	&lt;p&gt;This tip might actually target a small niche of Rails developers, but it&amp;#8217;s something that I couldn&amp;#8217;t find too much about when &amp;#8220;Googling&amp;#8221; for some help. So I eventually just came up with my own solution. It deals with creating an interface for legacy .NET &lt;span class="caps"&gt;SOAP&lt;/span&gt; web services. Rather than go into the explanation, I&amp;#8217;m going to provide an example skeleton class that you can tailor to your needs:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;digest/sha1&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;require&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;soap/wsdlDriver&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="keyword"&gt;module &lt;/span&gt;&lt;span class="module"&gt;WebServices&lt;/span&gt;
  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;SOAPInterface&lt;/span&gt;
    &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:endpoint&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:service&lt;/span&gt;

    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;endpoint&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;www.yoursite.com&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;service&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;YourWebServices&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="ident"&gt;options&lt;/span&gt;&lt;span class="punct"&gt;={})&lt;/span&gt;
      &lt;span class="attribute"&gt;@endpoint&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;endpoint&lt;/span&gt;
      &lt;span class="attribute"&gt;@service&lt;/span&gt;  &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;service&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="comment"&gt;# --&lt;/span&gt;
    &lt;span class="comment"&gt;# your methods go here&lt;/span&gt;
    &lt;span class="comment"&gt;# -- &lt;/span&gt;

    &lt;span class="ident"&gt;private&lt;/span&gt;
      &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;wsdl&lt;/span&gt;
        &lt;span class="constant"&gt;SOAP&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;WSDLDriverFactory&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;http://&lt;span class="expr"&gt;#{@endpoint}&lt;/span&gt;/services/&lt;span class="expr"&gt;#{@service}&lt;/span&gt;.asmx?WSDL&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;)&lt;/span&gt;    
      &lt;span class="keyword"&gt;end&lt;/span&gt;    
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# pulls out the diffgram of SOAP::Mapping::Object's into an array&lt;/span&gt;
  &lt;span class="keyword"&gt;class &lt;/span&gt;&lt;span class="class"&gt;DataSetParser&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;initialize&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;soap_response&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;data_set&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@response&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;soap_response&lt;/span&gt;
      &lt;span class="attribute"&gt;@data_set&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;data_set&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;

    &lt;span class="comment"&gt;# allows for @obj['CourseListing'] to be @obj.course_listing&lt;/span&gt;
    &lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;method_missing&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;*&lt;/span&gt;&lt;span class="ident"&gt;args&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
      &lt;span class="attribute"&gt;@response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:diffgram&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@data_set&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_sym&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;send&lt;/span&gt;&lt;span class="punct"&gt;(:[],&lt;/span&gt; &lt;span class="ident"&gt;name&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;to_s&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;camelize&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;We&amp;#8217;ll talk about about what goes in &amp;#8220;your methods go here&amp;#8221; in just a second. I wanted to mention what the &lt;code&gt;DataSetParser&lt;/code&gt; is all about. Firstly, it&amp;#8217;s specific to the .NET framework, so if you&amp;#8217;re wanting to use this for &lt;span class="caps"&gt;SOAP&lt;/span&gt; services coming from something other than .NET, you can wipe out the &lt;code&gt;DataSetParser&lt;/code&gt; class entirely. Now, onto what it does.&lt;/p&gt;


	&lt;p&gt;.NET returns it&amp;#8217;s data collections as a DataSet, which then gets wrapped in a DiffGram. I know, goofy. From the Microsoft site:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;A DiffGram is an &lt;span class="caps"&gt;XML&lt;/span&gt; format that is used to identify current and original versions of data elements. The DataSet uses the DiffGram format to load and persist its contents, and to serialize its contents for transport across a network connection.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;What does that mean to us? It means that it&amp;#8217;s another level of tedious parsing that we need to deal with when getting a &lt;span class="caps"&gt;SOAP&lt;/span&gt; response. If your &lt;span class="caps"&gt;API&lt;/span&gt; is returning a DataSet, then you can pass the result to the &lt;code&gt;DataSetParser&lt;/code&gt; class, and it will return the collection as an array of &lt;code&gt;SOAP::Mapping::Object&lt;/code&gt;. It also will allow you to access the data via an underscored method based on the camelized name of the DataSet returned. If that&amp;#8217;s confusing, see the comment above the &lt;code&gt;method_missing&lt;/code&gt; definition in the &lt;code&gt;DataSetParser&lt;/code&gt; class.&lt;/p&gt;


	&lt;p&gt;Now, here&amp;#8217;s an example of how you might use this skeleton module. Here, we&amp;#8217;ll be replacing the &amp;#8220;your methods go here&amp;#8221; comment.&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="comment"&gt;# returns a user in the form of a SOAP object&lt;/span&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;authenticate&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;username&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="ident"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;soap&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;wsdl&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;create_rpc_driver&lt;/span&gt;
  &lt;span class="ident"&gt;response&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;soap&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;Authenticate&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:username&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;username&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="symbol"&gt;:password&lt;/span&gt; &lt;span class="punct"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;result&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;response&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;authenticateResult&lt;/span&gt;
  &lt;span class="ident"&gt;soap&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;reset_stream&lt;/span&gt;
  &lt;span class="constant"&gt;DataSetParser&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;result&lt;/span&gt;&lt;span class="punct"&gt;,&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;user&lt;/span&gt;&lt;span class="punct"&gt;').&lt;/span&gt;&lt;span class="ident"&gt;user&lt;/span&gt;
&lt;span class="keyword"&gt;rescue&lt;/span&gt;
  &lt;span class="comment"&gt;# do your graceful error catching/logging stuff&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This would allow you to do something like:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;api&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;WebServices&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;SOAPInterface&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;new&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;www.mysite.com&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;MyWebServices&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="ident"&gt;api&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;authenticate&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;login&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;password&lt;/span&gt;&lt;span class="punct"&gt;')&lt;/span&gt;
&lt;span class="global"&gt;$&amp;gt;&lt;/span&gt; &lt;span class="comment"&gt;# =&amp;gt; &amp;lt;#SOAP::Mapping::Object ... &amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;The &lt;code&gt;Authenticate&lt;/code&gt; and &lt;code&gt;authenticateResult&lt;/code&gt; is dependent on the &lt;span class="caps"&gt;WSDL&lt;/span&gt; of the &lt;span class="caps"&gt;SOAP&lt;/span&gt; service, but the rest is pretty close to what each of your methods might look like. For more info, you can visit &lt;a href="http://rpheath.com/posts/298-consuming-soap-services-in-ruby"&gt;an earlier post of mine&lt;/a&gt; which discusses the same issues, and provides a more Rails-esque example.&lt;/p&gt;


	&lt;p&gt;Again, I realize that this is for a rather niche group of Rails developers, but like I said, I had a hard time finding any information on this, so maybe someone else will find my solution to this problem useful.&lt;/p&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;That concludes my 5 tips related to Rails. Hopefully they&amp;#8217;ve proven to be worthwhile. Let me know if you have any trouble implementing any of these tips, as I&amp;#8217;d be glad to help you make use of them. Thanks for reading my first novel :-)&lt;/p&gt;</description>
      <pubDate>Mon, 05 May 2008 00:12:46 -0400</pubDate>
      <link>http://rpheath.com/posts/323-railscasts-contest-5-rails-tips</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Entertainment</author>
      <title>Hulu: Online Movies and TV Shows</title>
      <description>&lt;p&gt;I just came across an awesome site for streaming TV shows and movies. It&amp;#8217;s called &lt;a href="http://www.hulu.com/"&gt;Hulu&lt;/a&gt;. Apparently it&amp;#8217;s a site supported (or built?) by &lt;span class="caps"&gt;NBC&lt;/span&gt;/Fox, so the videos are all of incredible quality. I came across it while looking at a list of high-traffic Rails applications (and it&amp;#8217;s one of them).&lt;/p&gt;


	&lt;p&gt;So if you&amp;#8217;re looking for another way to be distracted, check out &lt;a href="http://hulu.com"&gt;Hulu&lt;/a&gt;. Here&amp;#8217;s one to get you started: &lt;a href="http://www.hulu.com/tostitos-fiesta-bowl-2008"&gt;2008 Tostitos Fiesta Bowl&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Sun, 04 May 2008 00:05:56 -0400</pubDate>
      <link>http://rpheath.com/posts/322-hulu-online-movies-and-tv-shows</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Programming</author>
      <title>Testing block helpers with Rspec</title>
      <description>&lt;p&gt;One of the many great things about Rspec is that it allows you to test helper methods. Helpers can be complex at times. And when it matters, they definitely need some testing love.&lt;/p&gt;


	&lt;p&gt;An example of a typical helper may be something like:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;h1&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="ident"&gt;text&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;h1 class='heading'&amp;gt;&lt;span class="expr"&gt;#{text}&lt;/span&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Then you can do &lt;code&gt;&amp;lt;%=h1 'Text Here' -%&amp;gt;&lt;/code&gt; in your views. That&amp;#8217;s trivial to test, so I won&amp;#8217;t go into that. The tricky tests (I think) deal with block helpers. Block helpers are extremely useful and can improve the readability of what&amp;#8217;s going on in your view(s). Probably the most useful case is when you have &lt;code&gt;&amp;lt;% if current_user.admin? %&amp;gt;&lt;/code&gt; scattered all over the place. Wouldn&amp;#8217;t it be better (and DRYer) to wrap that &amp;#8220;admin condition&amp;#8221; up in one place?&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="keyword"&gt;def &lt;/span&gt;&lt;span class="method"&gt;content_for_admin&lt;/span&gt;&lt;span class="punct"&gt;(&amp;amp;&lt;/span&gt;&lt;span class="ident"&gt;block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;yield&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="ident"&gt;current_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;admin?&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Pretty simple. But, how would you test that? Initially, I had somewhat of a hard time writing tests to see if the block was actually yielded or not. Here&amp;#8217;s what I do now, but I&amp;#8217;m open to (and seeking more) alternatives. Using the &lt;code&gt;content_for_admin&lt;/code&gt; helper as the guinea pig:&lt;/p&gt;


&lt;div class="code ruby"&gt;&lt;pre&gt;
&lt;span class="ident"&gt;describe&lt;/span&gt; &lt;span class="constant"&gt;ApplicationHelper&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="ident"&gt;attr_accessor&lt;/span&gt; &lt;span class="symbol"&gt;:_erbout&lt;/span&gt;
  &lt;span class="ident"&gt;fixtures&lt;/span&gt; &lt;span class="symbol"&gt;:users&lt;/span&gt;

  &lt;span class="ident"&gt;before&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:each&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;_erbout&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
    &lt;span class="attribute"&gt;@block&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;This is the block content&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="attribute"&gt;@current_user&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;users&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:admin&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# current_user.admin? # =&amp;gt; true&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should yield block for an admin&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;should_receive&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:current_user&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;and_return&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@current_user&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@current_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_receive&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:admin?&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;and_return&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;true&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

    &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;content_for_admin&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;_erbout&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;div&amp;gt;&lt;span class="expr"&gt;#{@block}&lt;/span&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;html&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should&lt;/span&gt; &lt;span class="ident"&gt;have_tag&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="attribute"&gt;@block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;

  &lt;span class="comment"&gt;# current_user.admin? # =&amp;gt; false&lt;/span&gt;
  &lt;span class="ident"&gt;it&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;should not yield block for a non-admin&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
    &lt;span class="ident"&gt;should_receive&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:current_user&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;and_return&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="attribute"&gt;@current_user&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
    &lt;span class="attribute"&gt;@current_user&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_receive&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="symbol"&gt;:admin?&lt;/span&gt;&lt;span class="punct"&gt;).&lt;/span&gt;&lt;span class="ident"&gt;and_return&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;false&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;

    &lt;span class="ident"&gt;html&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="ident"&gt;content_for_admin&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
      &lt;span class="constant"&gt;self&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;_erbout&lt;/span&gt; &lt;span class="punct"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&amp;lt;div&amp;gt;&lt;span class="expr"&gt;#{@block}&lt;/span&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
    &lt;span class="keyword"&gt;end&lt;/span&gt;
    &lt;span class="ident"&gt;html&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;should_not&lt;/span&gt; &lt;span class="ident"&gt;have_tag&lt;/span&gt;&lt;span class="punct"&gt;('&lt;/span&gt;&lt;span class="string"&gt;div&lt;/span&gt;&lt;span class="punct"&gt;',&lt;/span&gt; &lt;span class="attribute"&gt;@block&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Another, similar, approach is to use &lt;code&gt;eval_erb&lt;/code&gt;, which let&amp;#8217;s you actually write out the &lt;span class="caps"&gt;ERB&lt;/span&gt; as a string (or heredoc) and evaluate the output. I think that&amp;#8217;s a little messy, but then again, I&amp;#8217;ve never actually tried it.&lt;/p&gt;


	&lt;p&gt;But other than that, this is the only way I know to test the yielded output of a block helper with Rspec. Do you know of a better way? Or at least, a different way?&lt;/p&gt;</description>
      <pubDate>Wed, 23 Apr 2008 08:42:15 -0400</pubDate>
      <link>http://rpheath.com/posts/321-testing-block-helpers-with-rspec</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Random</author>
      <title>Navigation Helper on GitHub</title>
      <description>&lt;p&gt;For those who are interested, I&amp;#8217;ve moved my &lt;a href="http://agilewebdevelopment.com/plugins/navigation_helper"&gt;navigation helper&lt;/a&gt; Rails plugin over to GitHub.&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://github.com/rpheath/navigation_helper/tree/master"&gt;http://github.com/rpheath/navigation_helper/tree/master&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;You can follow the changes there if you&amp;#8217;d like. To install (from your project root):&lt;/p&gt;


&lt;pre&gt;
git clone git://github.com/rpheath/navigation_helper.git vendor/plugins/navigation_helper
&lt;/pre&gt;

	&lt;p&gt;I doubt I&amp;#8217;ll be pushing changes to the subversion repo anymore, so use the above method if you want the latest and greatest.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 07:45:32 -0400</pubDate>
      <link>http://rpheath.com/posts/320-navigation-helper-on-github</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Web</author>
      <title>Flickr Developer Site</title>
      <description>&lt;p&gt;Flickr &lt;a href="http://blog.flickr.net/en/2008/04/16/codeflickrcom-new-flickr-developer-site/"&gt;launched a developer site&lt;/a&gt; recently (&lt;a href="http://code.flickr.com/"&gt;code.flickr&lt;/a&gt;). Dev sites intrigue me, especially those belonging to well-known companies. And for some reason, statements like this &lt;em&gt;always&lt;/em&gt; seem to draw me in:&lt;/p&gt;


	&lt;blockquote&gt;
		&lt;p&gt;In the last week we deployed new code to Flickr 50 times, including 546 changes by 16 people. We issued over 2,000 new &lt;span class="caps"&gt;API&lt;/span&gt; keys, and third party developers made an average of 704 &lt;span class="caps"&gt;API&lt;/span&gt; calls per second, across 109 public &lt;span class="caps"&gt;API&lt;/span&gt; methods. We added 1 new &lt;span class="caps"&gt;API&lt;/span&gt; method, and updated 7 others. There are approximately 10,000 lines of open source code in our public subversion repository.&lt;/p&gt;
	&lt;/blockquote&gt;


	&lt;p&gt;Sheesh, 704 &lt;span class="caps"&gt;API&lt;/span&gt; calls per second!? To interface with an &lt;span class="caps"&gt;API&lt;/span&gt; requires a slight bit of knowledge (and actual skill to do properly); I mean, it&amp;#8217;s not something cousin Elroy could just &amp;#8220;throw together&amp;#8221; real quick. So to think there are that many people making that many requests per second is kind of crazy.&lt;/p&gt;


	&lt;p&gt;You can find running totals for those types of stats at the bottom of the main &lt;a href="http://code.flickr.com"&gt;code.flickr&lt;/a&gt; page. Pretty cool.&lt;/p&gt;</description>
      <pubDate>Thu, 17 Apr 2008 00:15:45 -0400</pubDate>
      <link>http://rpheath.com/posts/319-flickr-developer-site</link>
    </item>
    <item>
      <author>Ryan Heath | filed under Technology</author>
      <title>Git and GitHub: Wow.</title>
      <description>&lt;p&gt;I&amp;#8217;m just getting my feet wet with Git, but it&amp;#8217;s starting to amaze me more and more. At first, I thought, &amp;#8220;Yeah, Git sounds pretty cool, but I can&amp;#8217;t see learning a new &lt;span class="caps"&gt;VCS&lt;/span&gt;. I know &lt;span class="caps"&gt;SVN&lt;/span&gt; and it&amp;#8217;s fine.&amp;#8221; Wrong. Wrong. Wrong. Learn it and &lt;span class="caps"&gt;LOVE&lt;/span&gt; it.&lt;/p&gt;


	&lt;h2&gt;Git is Distributed&lt;/h2&gt;


	&lt;p&gt;Git is a distributed &lt;acronym title="Version Control System"&gt;VCS&lt;/acronym&gt; as opposed to a centralized one. And what exactly does that mean? It means it&amp;#8217;s faster, safer, and far better for collaboration.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s faster because all changes are committed locally, then pushed to the server at once. So there&amp;#8217;s no need to have access to a &lt;del&gt;&lt;span class="caps"&gt;SVN&lt;/span&gt;&lt;/del&gt; server at all times. You can imagine the performance gains you get from this. And subconsciously, having those somewhat expensive operations become nearly instantaneous makes you think/work a different way. A better way.&lt;/p&gt;


	&lt;p&gt;It&amp;#8217;s safer because for each user who works with the code, there are multiple versions of the repository (each user essentially has his/her own copy (or branch) of the code). With a centralized &lt;span class="caps"&gt;VCS&lt;/span&gt; (i.e. Subversion), if the server hosting the &lt;em&gt;single&lt;/em&gt; repository were to die, you had better hope there&amp;#8217;s a backup somewhere. Otherwise, all is lost.&lt;/p&gt;


	&lt;p&gt;For a lot of (maybe most?) people using Git, collaboration is where its distributed nature shines. You can commit to your hearts content without disturbing anyone else. There aren&amp;#8217;t any permissions issues because it&amp;#8217;s all local to your machine. You can fork any project, change it however you see fit, then others can pull from your forked repo and merge with their own. And then &lt;em&gt;that&lt;/em&gt; person can modify your already modified code, improve it, then tell &lt;em&gt;their&lt;/em&gt; friends and they can fork the doubly modified repo, and, well, you see how this &amp;#8220;network effect&amp;#8221; can make projects blossom. This is entirely different from requiring commit rights to the one-and-only, centralized, repository. It&amp;#8217;s a hard model to grasp at first, but it&amp;#8217;s incredibly cool once you do.&lt;/p&gt;


	&lt;h2&gt;Branching and Merging&lt;/h2&gt;


	&lt;p&gt;Aside from being distributed, another thing that attracts me to Git is how branches work. Git &lt;em&gt;encourages&lt;/em&gt; you to work from a branch, which is great because in concept a branch is ideal for experimenting with a feature. They remove the worry of &amp;#8220;screwing up&amp;#8221; existing code. And in Git, each &amp;#8220;checkout&amp;#8221; is actually a branch of the main repo, anyway. So naturally, merging branches works much better than that of many other systems. I think the creator of Git himself said he merges (on a 22,000 file project&amp;#8212;the Linux Kernel) on average 4.5 times per day. That&amp;#8217;s &lt;em&gt;a lot&lt;/em&gt;.&lt;/p&gt;


	&lt;p&gt;Another cool thing, if you&amp;#8217;ve branched (or forked) a repo that you don&amp;#8217;t own, you can tell the owner about it (send a pull request) and he/she can merge it with the master branch if it&amp;#8217;s worthy. And even if it&amp;#8217;s not worthy, someone else might have the same need as you, and fork your forked repo instead of the master.&lt;/p&gt;


	&lt;h2&gt;Learn it. Love it.&lt;/h2&gt;


	&lt;p&gt;At first, I thought having to explicitly add files to the &amp;#8220;staging area&amp;#8221; was tedious and annoying. Now I think it&amp;#8217;s brilliant. It provides more control. I add the &lt;del&gt;files&lt;/del&gt; content of my choosing to the index for the next commit, so the commit messages are always meaningful, and it doesn&amp;#8217;t hold back my work flow at all. Which brings me to another wonderful thing about Git: it tracks &lt;em&gt;content&lt;/em&gt; not files. With Subversion, you know those .svn folders littered all throughout &lt;em&gt;every&lt;/em&gt; folder in your entire project? Git just has one .git folder in the project root. And better yet, you remember having to tell Subversion you were deleting/moving &lt;em&gt;each and every&lt;/em&gt; file (&lt;code&gt;svn mv&lt;/code&gt; and &lt;code&gt;svn rm&lt;/code&gt;)? No more. Git doesn&amp;#8217;t care what you do. It&amp;#8217;s smart enough to figure it out when the time comes.&lt;/p&gt;


	&lt;p&gt;Not sold yet? A great article called, &lt;a href="http://tomayko.com/writings/the-thing-about-git"&gt;The Thing About Git&lt;/a&gt; shows some advanced usage of Git, and in particular, the infamous &lt;em&gt;Tangled Working Copy Problem&lt;/em&gt; that &lt;em&gt;every&lt;/em&gt; developer using source control has dealt with. Go read it if you haven&amp;#8217;t already.&lt;/p&gt;


	&lt;p&gt;So, I agree with everyone else who already realizes Git is awesome, because, well, Git is awesome.&lt;/p&gt;


	&lt;h2&gt;GitHub&lt;/h2&gt;


	&lt;p&gt;And then there&amp;#8217;s &lt;a href="http://github.com"&gt;GitHub&lt;/a&gt;, a place to host your Git repositories. It was built by the guys at &lt;a href="http://errfree.com/"&gt;err free&lt;/a&gt;, so you know it&amp;#8217;s slick. GitHub really wraps a nice interface around the inherent benefits of Git itself. It&amp;#8217;s said to be a &amp;#8220;social network for programmers&amp;#8221;.&lt;/p&gt;


	&lt;p&gt;They just launched publicly the other day. (I got in early as one of the beta users) With the launch, they&amp;#8217;ve released two new features: &lt;a href="http://github.com/blog/42-commit-comments"&gt;commit comments&lt;/a&gt; and the &lt;a href="http://github.com/blog/39-say-hello-to-the-network-graph-visualizer"&gt;network graph visualizer&lt;/a&gt;. Both incredibly useful and impressive, as expected.&lt;/p&gt;


	&lt;p&gt;The commit comments are similar to those of the &lt;a href="http://www.djangobook.com/"&gt;Django Book&lt;/a&gt;. But since we&amp;#8217;re dealing with commits, the comments can be per line of source code or per commit. Very cool.&lt;/p&gt;


	&lt;p&gt;And the network graph visualizer is cool because it exposes how Git actually works. If you read &lt;a href="http://github.com/blog/39-say-hello-to-the-network-graph-visualizer"&gt;the post about the network visualizer&lt;/a&gt;, you&amp;#8217;ll get to a part that says &amp;#8220;think of this as a to-do list,&amp;#8221; which at first, I didn&amp;#8217;t get. Now I do. As I said earlier, with Git, you can fork a repository and make your own changes separate of the master branch. That&amp;#8217;s just awesome in itself, and what&amp;#8217;s even cooler is you can choose to pull changes from a forked repo back into yours. What the network graph does is show you what things others have been up to in relation to your code. But it only shows code that you have not yet pulled into your repo. Once (if) you do, it goes away, hence the comparison to a to-do list. And try clicking a user to the left, they become the root and the graph changes. Nice.&lt;/p&gt;


	&lt;h2&gt;Conclusion&lt;/h2&gt;


	&lt;p&gt;Overall I&amp;#8217;ve got a long way to go with Git, but it&amp;#8217;s exciting to keep learning it. Even as a beginner, I&amp;#8217;m finding that I&amp;#8217;m able to do more with Git than if I were using a centralized &lt;span class="caps"&gt;VCS&lt;/span&gt;.&lt;/p&gt;</description>
      <pubDate>Tue, 15 Apr 2008 17:24:52 -0400</pubDate>
      <link>http://rpheath.com/posts/318-git-and-github-wow</link>
    </item>
  </channel>
</rss>
