<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Biodegradable Geek &#187; Ruby on Rails</title>
	<atom:link href="http://biodegradablegeek.com/category/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://biodegradablegeek.com</link>
	<description></description>
	<lastBuildDate>Tue, 22 Jun 2010 21:52:41 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=</generator>
		<item>
		<title>Refactoring Tip: Eliminating Model.find(params[:id]) Duplication</title>
		<link>http://biodegradablegeek.com/2008/12/refactoring-tip-eliminating-modelfindparamsid-duplication/</link>
		<comments>http://biodegradablegeek.com/2008/12/refactoring-tip-eliminating-modelfindparamsid-duplication/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 15:59:36 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[refactoring tips]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=293</guid>
		<description><![CDATA[In a controller, you&#8217;ll commonly have a method that requires you have an instance variable containing the object you&#8217;re working with. An example would be the show, edit, update, and destroy methods (REST). To eliminate having find(params[:id]) in multiple methods, you can use before_filter, like this: class Admin::PostsController < Admin::ApplicationController before_filter :find_post, :only => [:show, [...]]]></description>
			<content:encoded><![CDATA[<p>In a controller, you&#8217;ll commonly have a method that requires you have an instance variable containing the object you&#8217;re working with. An example would be the <strong>show</strong>, <strong>edit</strong>, <strong>update</strong>, and <strong>destroy</strong> methods (REST).</p>
<p>To eliminate having find(params[:id]) in multiple methods, you can use before_filter, like this:</p>
<pre lang="rails">
class Admin::PostsController < Admin::ApplicationController
  before_filter :find_post, :only => [:show, :edit, :update, :destroy]
  rescue_from(ActiveRecord::RecordNotFound) { |e| render :text => "
<h2>Post not found</h2>

" }

  def index
    @posts = Post.find(:all)
  end

  def show
  end

  def new
    @post = Post.new
  end

  def create
    @post = Post.new
  end

  def edit
  end

  def update
  end

  def destroy
  end

protected
  def find_post(id = params[:id])
    @post = Post.find(id)
  end
end
</pre>
<p>(Thanks Jon)</p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/12/refactoring-tip-eliminating-modelfindparamsid-duplication/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using Javascript to Populate Forms During Development</title>
		<link>http://biodegradablegeek.com/2008/12/using-javascript-to-populate-forms-during-development/</link>
		<comments>http://biodegradablegeek.com/2008/12/using-javascript-to-populate-forms-during-development/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 15:43:41 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Automation]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Snippets]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=291</guid>
		<description><![CDATA[During development, working with forms quickly gets annoying because you have to constantly fill in each field, sometimes with unique info. One way around this is to write a little Javascript code that just populates the fields. I use something like this on the bottom of the form. I had jQuery no-conflict mode on in [...]]]></description>
			<content:encoded><![CDATA[<p>During development, working with forms quickly gets annoying because you have to constantly fill in each field, sometimes with unique info. One way around this is to write a little Javascript code that just populates the fields. I use something like this on the bottom of the form. I had jQuery no-conflict mode on in this case. In your app you might be able to get away replacing _j() with $():</p>
<pre lang="rails">
<% if ENV['RAILS_ENV']=='development' -%>
<!-- Generate random field data -->
<script lang="text/javascript">
  jQuery(function() {
    if (typeof(_j)=='undefined') _j = jQuery;
    function randstr() {
      return Math.floor(Math.random()*99999)
    }

    _j('#name').val('Chuck Norris');
    _j('#company_name').val('Roundhouse LLC');
    _j('#email').val('moo'+randstr()+'@yawhoo.com');
    _j('#login').val('user'+randstr());
    _j('#password').val('admin');
    _j('#password_confirmation').val('admin');
  })
</script>
<% end -%>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/12/using-javascript-to-populate-forms-during-development/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Mephisto for the Masses &#8211; Installation HOWTO</title>
		<link>http://biodegradablegeek.com/2008/10/mephisto-for-the-masses-installation-howto/</link>
		<comments>http://biodegradablegeek.com/2008/10/mephisto-for-the-masses-installation-howto/#comments</comments>
		<pubDate>Wed, 22 Oct 2008 02:14:00 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Workarounds]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[deploying]]></category>
		<category><![CDATA[howto]]></category>
		<category><![CDATA[installing]]></category>
		<category><![CDATA[logs]]></category>
		<category><![CDATA[mefisto]]></category>
		<category><![CDATA[mephisot]]></category>
		<category><![CDATA[mephisto]]></category>
		<category><![CDATA[mephsto]]></category>
		<category><![CDATA[mod_rails]]></category>
		<category><![CDATA[phusion passanger]]></category>
		<category><![CDATA[redcloth-3.0.4]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=257</guid>
		<description><![CDATA[I&#8217;ve recently taken a fancy to Mephisto, a blogging-platform written in Rails. I have nothing against WordPress, but being in Ruby and using Liquid for themes, Mephisto is far easier (and more fun) to tweak and configure, especially when I want to migrate my sites away from the &#8220;blog look&#8221; and make them more dynamic. [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently taken a fancy to Mephisto, a blogging-platform written in Rails. I have nothing against WordPress, but being in Ruby and using Liquid for themes, Mephisto is far easier (and more fun) to tweak and configure, especially when I want to migrate my sites away from the &#8220;blog look&#8221; and make them more dynamic. </p>
<p>It&#8217;s unfortunate development isn&#8217;t as active as say, Typo (also a Rails app, but I haven&#8217;t tried it), but I find that Mephisto at its current level makes a simple and <strong>fast</strong> starting point for most of my projects. </p>
<p>The point of this post is to address numerous problems with the installation. These are present in the tarball release of 0.8 Drax, and in trunk (as of 10/21). </p>
<h3>Git The Code</h3>
<p>Get the files, either the <a href="http://github.com/technoweenie/mephisto/tree/master">compressed archive</a> or from edge (recommended).</p>
<pre lang="text">
git clone git://github.com/technoweenie/mephisto.git
</pre>
<h3>Pre-installation</h3>
<p>You&#8217;ll need to freeze rails 2.0.2, and have the latest tzinfo gem installed:</p>
<pre lang="text">
gem install tzinfo
cd mephisto/
rake rails:freeze:edge RELEASE=2.0.2
</pre>
<p>The file it downloads should be named rails_2.0.2.zip and NOT rails_edge.zip. </p>
<p>Copy the &#8220;new&#8221; boot.rb into the config/ folder, overwriting the existing one:</p>
<pre lang="text">
cp vendor/rails/railties/environments/boot.rb config/boot.rb
</pre>
<p>Now rename the database sample file in config/ to database.yml and edit it to fit your own DB settings. You&#8217;ll probably only be using production.</p>
<h3>Bootstrapping</h3>
<p>Now bootstrap:</p>
<pre lang="text">
rake db:bootstrap RAILS_ENV=production
</pre>
<p>If it works, GREAT. But you&#8217;ll probably get an error or two. If you&#8217;re getting the following error: </p>
<pre lang="text">
Error message:
  undefined method `initialize_schema_information' for module
  `ActiveRecord::ConnectionAdapters::SchemaStatements'
Exception class:
  NameError
</pre>
<p>You forgot to copy over boot.rb from vendor/rails/ &#8211; scroll up. If you&#8217;re getting an error that redcloth is missing (<em>no such file to load—RedCloth-3.0.4/lib/redcloth</em>), even though it&#8217;s in vendor/, it&#8217;s because the path to RedCloth is relative in <strong>config/environment.rb</strong>. Change it from:</p>
<pre lang="rails">
require '../vendor/RedCloth-3.0.4/lib/redcloth' unless Object.const_defined?(:RedCloth)
</pre>
<p>to</p>
<pre lang="rails">
require File.join(File.dirname(__FILE__), '../vendor/RedCloth-3.0.4/lib/redcloth') unless Object.const_defined?(:RedCloth)
</pre>
<h3>Running</h3>
<p>After the bootstrap, you may either start the server (ruby script/server, thin, mongrel, etc), or go with <a href="http://www.modrails.com/">mod_rails (Phusion Passanger)</a>. I recommend the latter &#8211; Passenger is amazing, and the error screen is pretty. </p>
<p>Just point your Apache2 vhost to Mephisto&#8217;s PUBLIC/ dir. Here&#8217;s an example:</p>
<pre lang="text">
<VirtualHost *:80>
   ServerAdmin mrEman@domain.com
   ServerName domain.com
   ServerAlias www.domain.com

   # DocumentRoot must be rails_app/public/
   DocumentRoot /home/kiwi/www/domain.com/public/public
   Railsenv production

   DirectoryIndex index.html index.htm index.php
   ErrorLog /home/blue/www/domain.com/log/error.log
   CustomLog /home/blue/www/domain.com/log/access.log combined
</VirtualHost>
</pre>
<p>Restart Apache2, and you&#8217;re done. The site should work right away. If you get the following error:</p>
<pre lang="text">
No such file or directory - /tmp/mysql.sock
</pre>
<p>It&#8217;s because the socket file resides somewhere else on your (host&#8217;s) distro. Just find (man find, locate, etc) and add a symlink to it. Here&#8217;s an example (Debian): </p>
<pre lang="text">
ln -s /var/run/mysqld/mysqld.sock mysql.sock
</pre>
<p>If you&#8217;re getting an error that gems you know you have aren&#8217;t found, like:</p>
<pre lang="text">
no such file to load -- tzinfo (MissingSourceFile)
</pre>
<p>it is due to the fact that Gems are not located anywhere Ruby checks. You&#8217;ll have to explicity pass Ruby -rubygems or require &#8216;rubygems&#8217; &#8212; what a nuisance. Open config/environment.rb and add the latter line:</p>
<pre lang="text">
# requires vendor-loaded redcloth
require 'rubygems'
</pre>
<p>This will be global. Now either restart the server you ran (i.e., thin), or tell mod_rails to restart the app. To do so, just create a file named &#8220;restart.txt&#8221; in the tmp/ folder of the RAILS app:</p>
<pre lang="text">
cd mephisto_root/
touch tmp/restart.txt
</pre>
<p>and refresh the page. Passenger will restart the app and restart.txt will vanish. </p>
<p>The default login for the /admin page is <strong>admin/test</strong>. <em>Wasn&#8217;t that a blast? </em></p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/10/mephisto-for-the-masses-installation-howto/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How To Use Fixtures to Populate Your Database in Rails</title>
		<link>http://biodegradablegeek.com/2008/07/how-to-use-fixtures-to-populate-your-database-in-rails/</link>
		<comments>http://biodegradablegeek.com/2008/07/how-to-use-fixtures-to-populate-your-database-in-rails/#comments</comments>
		<pubDate>Fri, 11 Jul 2008 05:58:56 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[fixtures]]></category>
		<category><![CDATA[migrations]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/?p=121</guid>
		<description><![CDATA[UPDATE: I&#8217;ve been using this method for awhile now: http://railspikes.com/2008/2/1/loading-seed-data Seed data is data that the app is dependent on. It is data that has to exist if you were to wipe the database clean and reload your schema. Some examples would be a list of cities/states, a list of categories, or the initial &#8216;admin&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE: I&#8217;ve been using this method for awhile now: <a href="http://railspikes.com/2008/2/1/loading-seed-data" target="_blank">http://railspikes.com/2008/2/1/loading-seed-data</a></strong></p>
<p>Seed data is data that the app is dependent on. It is data that has to exist if you were to wipe the database clean and reload your schema. Some examples would be a list of cities/states, a list of categories, or the initial &#8216;admin&#8217; user account.</p>
<p>Most people looking at this thread want seed data rather than to populate their database with test/generated content. For the latter, you can go the route below or try <a href="http://github.com/sevenwire/forgery/tree/master" target="_blank">Forgery </a></p>
<p>&#8212;</p>
<p><em>This is a response to the email I&#8217;ve been getting asking me how to use fixtures to load data into a database.</em></p>
<p>You want to create dummy entries in your Rails app, either for testing, for development, or for production, to make your site appear popular. Whatever the reason, populating your database can be done easily using fixtures.</p>
<p>While rake/fixtures/migrations can get a lot more complex, this will be a brief introductory example.</p>
<h1>Initial App setup</h1>
<pre lang="bash">$ rails characters
$ cd characters/</pre>
<p>Edit config/database.yml &#8211; We only need a development database. So open up PHPMyAdmin or the MySQL command shell and:</p>
<pre lang="sql">mysql&gt; CREATE database characters_development;
Query OK, 1 row affected (0.00 sec)</pre>
<p><em>(I&#8217;m assuming you&#8217;re using MySQL. You can use anything; SQLite, Postgres, etc..) </em></p>
<h3>Create a model and a table in the database (using a migration)</h3>
<pre lang="rails">$ script/generate model Character
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/character.rb
      ....

$ vim db/migrate/001_create_characters.rb</pre>
<p>Sexy migration:</p>
<pre lang="rails">class CreateCharacters &lt; ActiveRecord::Migration
  def self.up
    create_table :characters do |t|
      t.string  :name, :alias, :motto
      t.timestamps
    end
  end

  def self.down
    drop_table :characters
  end
end</pre>
<p>Now migrate development (default environment):</p>
<pre lang="bash">$ rake db:migrate</pre>
<h3>Create the characters fixture</h3>
<pre lang="bash">$ vim test/fixtures/characters.yml</pre>
<p><span id="more-85"></span><br />
This is a <a href="http://en.wikipedia.org/wiki/YAML">YAML</a> file. It is easy to read and easy to edit. <em>(One may also use the CSV format, extension .csv).</em></p>
<p>Some notes:</p>
<ul>
<li>Each model has a corresponding fixture file with the same name in the <strong>test/fixtures/</strong> path in your app&#8217;s root directory.</li>
<li>Each &#8216;fixture&#8217; is a record in the database table, and consists of a label, and then values for each field (i.e., name, age, etc..).</li>
<li>Optional fields can be skipped. They will default to either NULL, or their default value set in the database.</li>
<li>The id doesn&#8217;t need to be specified. It will be auto-incremented automatically, but be careful of conflicts if you&#8217;re specifying the ID for some fixtures and not others.</li>
<li>Whitespace matters. Make it purty.</li>
<li>You may embed Ruby code in the fixture file, in both the YAML and CSV fixture formats. (i.e., &lt;% f() -%&gt; or created_at: &lt;%= Time.now %&gt;)</li>
<li>To load fixtures, you use <strong>rake db:fixtures:load</strong>. This loads the fixtures into your current environment (can be set via RAILS_ENV shell var or in config/environment.rb).<em>One thing that might be confusing is the fact that fixtures reside in test/. Many people believe that fixtures can only be used in the test environment, but this is not the case. </em></li>
<li>When a fixture are loaded, any data previously in the table will be wiped out. You don&#8217;t need to fear altering or losing your test data when testing (i.e., destroy methods, &#8230;), just reload the fixtures. In the test environment, fixtures may be loaded before each test case is run by using the fixtures method (fixtures :employees, :orders, &#8230;). Keep in mind that you&#8217;re using a freshly loaded fixtures between every case method (if you&#8217;re loading).</li>
</ul>
<p>This is what our fixture file should look like. I will dissect it below:</p>
<pre lang="yaml">riddler:
  name: Edward Nashton
  alias: Riddler
  motto: Riddle me this, riddle me that

pp:
  name: Peter Parker
  alias: Spiderman
  motto: One for JJ
  created_at: &lt;%= Time.now %&gt;
  updated_at: &lt;%= Time.now %&gt;

JILL:
  id: 101
  name: Jill Valentine
  motto: Im a member of S*T*A*R*S

dan_forden:
  name: Dan Forden
  motto: Toasty!

hotness:
  name: Sorceress
  motto: Time is mana

Airplane:
  name: Steve McCroskey
  motto: Looks like I picked the wrong week to quit sniffing glue.</pre>
<p>Let&#8217;s examine the first fixture:</p>
<pre lang="yaml">riddler:
  name: Edward Nashton
  alias: Riddler
  motto: Riddle me this, riddle me that</pre>
<pre lang="yaml">riddler:</pre>
<p>This is a name for the fixture. It begins at the beginning of the line, and it doesn&#8217;t matter what you call it. That information is not saved in the database and you might never use it. Ideally, names should be descriptive. You may also just go generic, &#8220;person1, person2, person3&#8243; etc.</p>
<p>When using the CSV format, fixture names are generated automatically and are in this format:</p>
<pre>model_name-counter</pre>
<p>In our example above, our fixtures would be named character-1, character-2, etc.</p>
<pre lang="yaml">  name: Edward Nashton
  alias: Riddler
  motto: Riddle me this, riddle me that</pre>
<p>These three are the values this fixture (record) will have in the database. They go under the fixture name, tabbed or spaced evenly. When going on to the next fixture, just leave a blank line.</p>
<p>The above is like doing this:</p>
<pre lang="rails">&gt;&gt; r = Character.new
&gt;&gt; r.name = 'Edward Nashton'
&gt;&gt; r.alias = 'Riddler'
&gt;&gt; r.motto = 'Riddle me this, riddle me that'
&gt;&gt; r.save</pre>
<p>id, created_at and updated_at are optional, but may be specified. Keep in mind that this file is going to be preprocessed with Ruby, so you may embed Ruby code (ERb) anywhere in the file.</p>
<h3>Load Fixture into Development Database</h3>
<p>This loads fixtures into the current RAILS_ENV, which, by default, is development.</p>
<pre lang="bash">$ rake db:fixtures:load</pre>
<p>If you check your database now, you will find the fixtures you just loaded residing in the specific table. Let&#8217;s poke at this table in the Rails console.</p>
<pre lang="bash">$ script/console
&gt;&gt; them = Character.find(:all)
=&gt; [#&gt; them[0].name
=&gt; Edward Nashton

&gt;&gt; them[0].alias
=&gt; Riddler

&gt;&gt; them[0].motto
=&gt; Riddle me this, riddle me that</pre>
<p>See these links for more info:</p>
<h1>External links</h1>
<ul>
<li><a href="http://www.ryandaigle.com/articles/2007/10/26/what-s-new-in-edge-rails-fixtures-just-got-a-whole-lot-easier" target="_blank">Fixtures Just Got a Whole Lot Easier</a></li>
<li><a href="http://techpolesen.blogspot.com/2007/04/rails-fixture-tips.html" target="_blank">Rails Fixture Tips</a></li>
<li><a href="http://manuals.rubyonrails.com/read/chapter/26" target="_blank">The Lo-Down on Fixtures </a></li>
<li><a href="http://railscasts.com/episodes/81" target="_blank">Fixtures in Rails 2.0</a></li>
<li><a href="http://oomoo.wordpress.com/2008/03/11/migration-related-rake-commands/" target="_blank">Migration Related Rake Commands (Rake Cheatsheet)</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/07/how-to-use-fixtures-to-populate-your-database-in-rails/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Got API? Instantly Search API Documentation</title>
		<link>http://biodegradablegeek.com/2008/06/got-api-instantly-search-api-documentation/</link>
		<comments>http://biodegradablegeek.com/2008/06/got-api-instantly-search-api-documentation/#comments</comments>
		<pubDate>Sun, 01 Jun 2008 07:21:04 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tips]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/06/01/got-api-instantly-search-api-documentation/</guid>
		<description><![CDATA[gotAPI.com does an excellent job congregating API documentation for numerous programming languages under an AJAX interface. No more bulging neck veins or fulmination when you can&#8217;t remember the order of those pesky arguments. No support for your favorite language? Contribute. You can add a gotAPI Search Widget to your site: http://www.gotapi.com/widgets/index.html See Ruby/Rails widget below [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.gotapi.com/">gotAPI.com</a> does an excellent job congregating API documentation for numerous programming languages under an AJAX interface. No more bulging neck veins or fulmination when you can&#8217;t remember the order of those pesky <a href="http://project.ioni.st/post/790">arguments</a>.</p>
<p>No support for your favorite language? <a href="http://www.gotapi.com/contribute/index.html">Contribute</a>.</p>
<p>You can add a gotAPI Search Widget to your site: <a href="http://www.gotapi.com/widgets/index.html">http://www.gotapi.com/widgets/index.html</a><br />
See Ruby/Rails widget below (requires Javascript). Still in beta and might have UI issues, but it&#8217;s functional. Try typing <em>map</em> or <em>validates</em> and hitting enter.</p>
<p><!-- gotAPI.com search widget v2 begin --></p>
<div><!-- 	.gaMenu{border:1px solid #505050;background-color:#FAFAFA;padding:0px 5px 0px 5px;} 	.gaHeaderRow{font:bold 8pt Arial;color:#359155;border-top:1px solid #C0C0C0;width:250px;} 	.gaRegularRow,.gaFooterRow{font:8pt Arial;cursor:pointer;} 	.gaSelectedRow{font:8pt Arial;background-color:#c1e0e6;cursor:pointer;} --><script type="text/javascript"><!--
	gaMod='module_rubyrails.js';gaTitle='Ruby / Rails';updateWhenLoaded=false;
	var gaL=false;function gaInit(){if(gaL)return;gaL=true;var s=document.createElement('script');
	s.type='text/javascript';s.src='http://www.gotapi.com/widgets/compiled/c1_module_rubyrails.js.jsz';s.defer='defer';s.defered='yes';
	document.getElementById('gaInfo').parentNode.appendChild(s)}function gaSearching(){
	document.getElementById('gaWait').style.display='';updateWhenLoaded=true;
	document.getElementById('gaInfo').style.display='none'}
// --></script></p>
<div style="font:bold 10pt Arial">Quick Ruby / Rails lookup</div>
<input id="gaSearch" onkeydown="gaSearching()" size="20" />
<div id="gaInfo" style="font:7pt Arial">powered by <a style="padding:0px" href="http://www.gotapi.com">gotAPI.com</a></div>
<div id="gaWait" style="font:7pt Arial;display:none">Searching&#8230;</div>
</div>
<p><!-- gotAPI.com search widget v2 end --></p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/06/got-api-instantly-search-api-documentation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Way to Populate a Database in Rails</title>
		<link>http://biodegradablegeek.com/2008/03/simple-way-to-populate-a-database-in-rails/</link>
		<comments>http://biodegradablegeek.com/2008/03/simple-way-to-populate-a-database-in-rails/#comments</comments>
		<pubDate>Wed, 19 Mar 2008 01:23:31 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/03/18/simple-way-to-populate-a-database-in-rails/</guid>
		<description><![CDATA[This is how I populate my database when I have a lot of data but can&#8217;t be bothered to write more than a quick throw-away hack. This doesn&#8217;t use fixtures, nor migrations (nothing wrong with them, I wuv migrations). Just a ruby file and the Rails console (this is optional actually). I create a new [...]]]></description>
			<content:encoded><![CDATA[<p>This is how I populate my database when I have a lot of data but can&#8217;t be bothered to write more than a quick throw-away hack. This doesn&#8217;t use fixtures, nor migrations (nothing wrong with them, I wuv migrations). Just a ruby file and the Rails console (this is optional actually).</p>
<p>I create a new rb file in lib/ (you can put your files in a sub-directory or anywhere &#8216;load&#8217; can find them), then write the data I want inserted into the database in a new function in that file. I do so exactly as I would insert data in Rails. Model.create, Model.new, etc&#8230;</p>
<p>I then get into the Rails console (<em>ruby script/console</em>) and do <em>load &#8216;file.rb&#8217;</em> and simply call the function. The database used will vary according to the environment you&#8217;re in (test, development, etc). Using &#8216;load&#8217; every time you call your function(s) is preferred. Load will keep reloading the file (as opposed to &#8216;require&#8217; which only reads a file once), staying up to date with edits you&#8217;re making to the file. For example, in the console:</p>
<p><em>&gt;&gt; load &#8216;funk.rb&#8217;; add_default_settings</em></p>
<p><em>(funk.rb is in /lib/ and add_default_settings is a function in that file) </em></p>
<p>As of 2.x, Rails now has rake db:migrate:reset and db:migrate:redo, which sends you down one migration and then back up to the current migration (or you can decide how many hops to take back using STEP=n). This is great, especially for tasks like populating a database.</p>
<p>So why don&#8217;t I use migrations? I do, but sometimes, especially in a proof-of-concept or throw-away app, I find it faster to skip the proper methods and write up  a quick function. If you think that&#8217;s bad, you should see my lingering Python addiction. Sometimes I catch myself metaprogramming Ruby code in Python.</p>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/03/simple-way-to-populate-a-database-in-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Introduction to Validations &amp; Validation Error Handling in Rails</title>
		<link>http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/</link>
		<comments>http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/#comments</comments>
		<pubDate>Sat, 09 Feb 2008 02:47:50 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[error handling]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[regex]]></category>
		<category><![CDATA[regular expressions]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[validations]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/02/08/introduction-to-validations-validation-error-handling-in-rails/</guid>
		<description><![CDATA[Validations in Ruby on Rails are essentially nothing more than methods that ensure that the data in a model is valid before saving it to the database. Traditionally, we validate data coming in using conditional expressions (for example, if email != NULL or if passwd==passwd_confirmation). This task is essential, but boring and tedious, but Rails&#8217; [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://biodegradablegeek.com/wp-content/uploads/2007/12/purple_security_keypad_nitraguard1.jpg" alt="purple security keypad nitraguard1 Introduction to Validations &#38; Validation Error Handling in Rails" align="left" title="Introduction to Validations &#38; Validation Error Handling in Rails" /></p>
<p>Validations in Ruby on Rails are essentially nothing more than methods that ensure that the data in a model is valid before saving it to the database. Traditionally, we validate data coming in using conditional expressions (for example, <em>if email != NULL</em> or <em>if passwd==passwd_confirmation</em>). This task is essential, but boring and tedious, but Rails&#8217; validations make this mundane part of programming as simple and as easy as possible. The validations provided in Rails (defined in every model) are thorough, likely covering all your needs right out of the box. There are even validations provided for checking whether a user agreed to a Terms of Service or End-User License Agreement (EULA), and for doing automatic field confirmation, useful when you ask the user for an email or password twice to ensure no misspelling.<br />
<span id="more-51"></span></p>
<p>Let&#8217;s get to work with a simple step-by-step example (If you&#8217;d prefer a crash course, the <a href="http://wiki.rubyonrails.org/rails/pages/HowtoValidate">HowToValidate</a> wiki page is likely all you need.) We will create an application to help cat shelters keep track of each kitty coming in. It will take information about a cat that has been brought to a shelter, validate it and then save it in a database.</p>
<h2>Brand Spankin&#8217; New</h2>
<p>Begin by creating a new rails project:</p>
<pre lang="bash">rails felinedb</pre>
<p>In Rails 2.0, the <a href="http://weblog.rubyonrails.org/2007/12/17/rails-2-0-2-some-new-defaults-and-a-few-fixes">default database is now SQLite3</a>. If you&#8217;d like to use MySQL, use:</p>
<pre lang="bash">rails -d mysql project_name</pre>
<p>If sticking with SQLite3, you&#8217;re set to go. If you&#8217;re using MySQL, configure config/database.yml appropriately, then create the development database (in Rails 2.0, you can use &#8220;rake db:create&#8221; instead of creating it by hand) before moving on.</p>
<p>Now generate a model named Cat:</p>
<pre lang="bash">ruby script/generate model Cat</pre>
<p>(use :Rgenerate model cat if using <a href="/2007/12/13/using-vim-as-a-complete-ruby-on-rails-ide/">rails.vim</a>).</p>
<p>Now let&#8217;s add some stuff to this model. This is not intended to be realistic, but merely to illustrate the use of validations.</p>
<p>Add the following to your 001_create_cats.rb migration file (this is what it looks like in rails 2.0):</p>
<pre lang="rails">class CreateCats  1
      t.integer :age, :weight
      t.boolean :fiv, :vaccinated
      t.timestamps
    end
  end

  def self.down
    drop_table :cats
  end
end</pre>
<p>and run <em>rake db:migrate</em>. :rescued is the date the cat was rescued. In practice, it&#8217;s better off being a date(time) object, but I made it a string to demonstrate validating a field against a regular expression. I also didn&#8217;t include :null and :default attributes for simplicity&#8217;s sake.</p>
<h2>Halt! Who Goes There? &#8211; Adding Validations to a Model</h2>
<p>We will setup the validations and poke at the model directly using the console, without creating any views.</p>
<p>So what needs to be validated?</p>
<ul>
<li>All fields except <em>comment</em> will be mandatory.</li>
<li>Name will be at least 2 characters.</li>
<li>Sex will be either M or F.</li>
<li>Vaccinated and FIV (<a href="http://en.wikipedia.org/wiki/Feline_immunodeficiency_virus">Feline Immunodeficiency Virus</a>, for those curious) will be either True or False.</li>
<li>Age must be between 1-30 (indoor cats live 10-20 years on average, outdoor, far less)</li>
<li>Weight should be no less than 1.</li>
<li>Rescued will be a date in the following format: MM/DD/YYYY</li>
<li>Comment may be left blank, but otherwise has a limit of 500 characters.</li>
</ul>
<p>Let&#8217;s translate this list into Rails validations. This is what our Cat model (app/models/Cat.rb) will look like</p>
<pre lang="rails">class Cat  2
  validates_inclusion_of :sex, :in => %w(M F), :message => 'must be M or F'
  validates_inclusion_of :vaccinated, :in => [true,false]
  validates_inclusion_of :fiv, :in => [true,false]
  validates_inclusion_of :age, :within => 1..30
  validates_each :weight do |record, attr, value|
      record.errors.add attr, 'should be a minimum of 1 pound' if value and value  /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/
  validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500
end</pre>
<p><strong> validates_presence_of :name, :sex, :age, :weight, :rescued</strong> Makes sure these fields are not left blank. You cannot validate the presence of a boolean using this method. See <a href="http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M001327">this</a>:</p>
<p><em>&#8220;If you want to validate the presence of a boolean field (where the real values are true and false), you will want to use validates_inclusion_of :field_name, :in => [true, false] This is due to the way Object#blank? handles boolean values. false.blank? # => true&#8221;</em></p>
<p><strong>validates_length_of :name, :minimum => 2:</strong> Make sure minimum length of name is 2 characters.</p>
<p><strong>validates_inclusion_of :sex, :in => %w(M F):</strong> Make sure sex is either the value &#8216;M&#8217; or &#8216;F&#8217;.</p>
<p><strong>validates_inclusion_of :vaccinated, :in => [true,false]:</strong> Make sure vaccinated is either true or false.</p>
<p><strong>validates_inclusion_of :age, :within => 1..30:</strong> Make sure age is within 1 &#8211; 30.</p>
<p><strong>validates_each block (for :weight)</strong>: validates_each can be used to create   a custom validation. This specific validation will fail, adding the error &#8220;weight should be a minimum of 1 pound,&#8221; if the attribute (:weight) value (input we received) is less than 1. We have &#8220;<strong>if value and</strong> value &lt; 1&#8243; because value cannot be nil, else &#8220;nil &lt; 1&#8243; will give us an error.</p>
<p><strong> validates_format_of :rescued, :with => /^[01][0-9]\/[0-9]{2}\/[0-9]{4}$/:</strong> compares the given attribute&#8217;s value with a <a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a> (regex).</p>
<p>In this case, the regex you see makes sure the format is, in English: &#8220;a 0 or 1, followed by anything between 0-9 (this will be the month, MM), followed by a forward slash (we escaped it, hence \/ instead of just /), followed by 2 numbers (that&#8217;s what the {2} is for &#8211; this will be day, DD) between 0-9, followed by another forward slash, and ending with 4 numbers, each between 0-9, the year, YYYY.</p>
<p><strong>validates_length_of :comment, :allow_blank => true, :allow_nil => true, :maximum => 500</strong>: This is used to validate the number of characters in a field. Maximum should not be confused with a maximum numerical value, as this attribute does not treat numbers numerically &#8211; 583 is 3 characters.</p>
<p>This particular example keeps the comment optional (allow_nil/allow_blank), but restricts the comment to being at most 500 characters.</p>
<p>For more details about these methods and more, see <a href="http://rails.rubyonrails.com/classes/ActiveRecord/Validations/ClassMethods.html">this page</a>.</p>
<p>Validations are active on a model&#8217;s save method. This is the default behavior but can be changed using the &#8220;on&#8221; attribute (I.e., :on =&gt; :update). Model.save returns false if any of the  validations fail, and the model&#8217;s Errors object can be used to iterate through the automatically generated errors (unless explicitly overridden) to find out what went wrong and prompt the user to edit and re-submit the data. You can check the validity of a model before attempting to save it by using the model&#8217;s <em>valid?</em> method.</p>
<h2>Usage &amp; Handling Errors</h2>
<p>Let&#8217;s go into the Rails console (<em>ruby script/console</em>) and inspect the validations and Errors object. Create an instance of the Cat model and then try saving it:</p>
<pre lang="rails">
>> c = Cat.new
=> #
>> c.valid?
=> false
>> c.save
=> false</pre>
<p>The <em>save</em> method failed because the model is not valid. Without the validations in place, the save would have went through, simply filling a record in the database with NULLs in every field. We would have been manually checking each field (&#8220;if name&#8230;&#8221;), but Rails is doing this for us.</p>
<p>You can bypass the validations by passing <em>false</em> to the save method. For example:</p>
<pre lang="rails">
>> c.save false
=> true
>> c
=> #</pre>
<p>As you can see, this results in nil values being stored in the database. The usual approach to a failed save is to prompt the user about what happened and wait for proper input. When a validation fails, Rails automagically pushes a detailed (human-friendly) message to the model&#8217;s Errors stack.</p>
<p>Let&#8217;s observe the Errors object with a new Cat instance:</p>
<pre lang="rails">
>> o = Cat.new
>> o.save
=> false
>> o.errors.size
=> 13
>> o.errors.class
=> ActiveRecord::Errors</pre>
<p>Attempting to save the new Cat object failed, leaving us with 13 errors. No errors are generated if the model isn&#8217;t saved (obviously), but they are generated if the valid? method is envoked.</p>
<p>To see the other methods available in the Errors class, you can use the <em>methods</em> method. Preferably making it more readable:</p>
<pre lang="rails">
>> puts o.errors.methods.sort
  ... (omitted) ...
  []
  __id__
  __send__
  add
  add_on_blank
  add_on_boundary_breaking
  blank?
  class
  clear
  clone
  collect
  copy_instance_variables_from
  count
  daemonize
  dclone
... (omitted) ...</pre>
<p>For the entire list of errors method and details, see <a href="http://rails.rubyonrails.com/classes/ActiveRecord/Errors.html">this page</a>.</p>
<p>From the list, we can see that a subscript operator ([]) method is available. This method can be used to retrieve the error message generated for a particular attribute. This method is an alias for the <em>on</em> method; Either can be used. For example, we can pass the :name or :age attribute:</p>
<pre lang="rails">
>> o.errors[:name]
=> ["can't be blank", "is too short (minimum is 2 characters)"]

>> o.errors.on :sex
=> "must be M or F"</pre>
<p>We can iterate through this list using o.errors.each_full:</p>
<pre lang="rails">
>> o.errors.each_full {|msg| p msg}
  "Name can't be blank"
  "Name is too short (minimum is 2 characters)"
  "Weight can't be blank"
  "Gender can't be blank"
  "Gender must be M or F"
  "Vaccinated can't be blank"
  "Vaccinated is not included in the list"
  "Fiv can't be blank"
  "Fiv is not included in the list"
  "Age can't be blank"
  "Age is not included in the list"
  "Rescued can't be blank"
  "Rescued is invalid"</pre>
<p>Let&#8217;s create a new instance, and purposely pass invalid info for sex, weight, and rescued:</p>
<pre lang="rails">
>> y = Cat.new
>> y.valid?
=> false
>> y.update_attributes({:name => 'Thumbelina', :age => 5, :sex => 'E', :weight => 0, :rescued => '28/03/1965', :vaccinated => true, :fiv => false, :comment => 'Kitty attempted to buy cigarettes with a fake ID'})
=> false</pre>
<p>The returned false indicates it wasn&#8217;t saved, and hence, not valid. Let&#8217;s inspect further:</p>
<pre lang="rails">y.errors.each_full { |msg| p msg}
"Weight should be a minimum of 1 pound"
"Sex must be M or F"
"Rescued is invalid"</pre>
<p>Let&#8217;s correct these errors and finally save the model.</p>
<pre lang="rails">
>> y.update_attribute(:sex, 'F')
>> y.weight = 12
>> y.rescued = '03/28/1965'
>>; y.valid?
=> true
>> y.save
=> true</pre>
<p>In a practical app, you would want the user to see these errors. This can be done by accessing the errors class in your view. Here&#8217;s an example:</p>
<pre lang="rails">
  <span style="font-weight: bold; color: red;">Failed to save new cat information due to the errors:</span>
<ul>
<li></li>
</ul>
</pre>
<h2>Take Two &#8211; Confirmation Fields in Views</h2>
<p>One thing you&#8217;ll do often is confirm important fields to make sure the input is flawless. An example is asking the user for his password twice upon registration, to greatly reduce the chance of a typo the first time around.</p>
<p>Rails provides a validation for this called <em><a href="http://api.rubyonrails.org/classes/ActiveRecord/Validations/ClassMethods.html#M001325">validates_confirmation_of</a></em>. It does a comparison of the two password fields for you in memory. You no longer have to do &#8220;if passwd == passwd_conf &#8230;&#8221; to confirm passwords or other fields. You can trust that if this validation passes, then both fields were equivalent.</p>
<p>Here&#8217;s how it works. All you have to do is create another field (input box) in your view, with the same name as the initial value you want to confirm against, but suffixed with a &#8220;_confirmation&#8221; in the name. </p>
<p>For confirmation of a field named &#8220;email&#8221; in our model for example, we would have one text_field called &#8220;email&#8221; and another called &#8220;email_confirmation.&#8221; Now in the model we would have a validation like this:</p>
<pre lang="rails">validates_confirmation_of :email</pre>
<p>. </p>
<p><em>You may need to use attr_accessor if you&#8217;re using form_for, otherwise you might get errors that email_confirmation doesn&#8217;t exist. and it doesn&#8217;t, it&#8217;s not part of the model. It&#8217;s only virtual, used when needed.</em></p>
<p>That&#8217;s basically it! Now this validation will fail if those two email fields aren&#8217;t the same.</p>
<p>Note: You need to add a few extra steps to this if you&#8217;re using a field that requires being altered right before being saved. You want to encrypt a password before saving it, for example, but if you alter the password, this would cause the validation to fail on save, since password no longer matches password_confirmation. There are ways around this. You can use :on =&gt; :create for instance, so that this validation only occurs upon Model.new.</p>
<p>This presents a problem if save fails for another reason (username taken, invalid email format, etc), as the field you altered will be refreshed back as-is, not as it was when the user entered it. So for example, they might see the password hash instead of the password they entered, if the form reloads due to an error. Anyway, you can use the <a href="http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html#M001299">before_create</a> hook, or before_validation, after_validation, or other hooks, but I&#8217;m straying from the main topic, so I&#8217;ll leave this issue here (for now).</p>
<p>Anyway! there&#8217;s really nothing more to it. Validations are powerful, but simple and straightforward to implement.</p>
<p><em>Thanks to <a href="http://flickr.com/photos/wolfteacher/1481749268/">wolfteacher2</a> for the photo!</em></p>
<h2>External Links</h2>
<ul>
<li><a href="http://dizzy.co.uk/ruby_on_rails/contents/active-record-validations">Validations overview and cheatsheets at Dizzy.co.uk</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/02/introduction-to-validations-validation-error-handling-in-rails/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Expanding List of Ruby on Rails Sites, Editors, Tutorials, Cheat Sheets and More</title>
		<link>http://biodegradablegeek.com/2008/01/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/</link>
		<comments>http://biodegradablegeek.com/2008/01/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/#comments</comments>
		<pubDate>Wed, 02 Jan 2008 18:24:29 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[Tools]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2008/01/02/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/</guid>
		<description><![CDATA[Most of these Ruby on Rails related links are right out of my bookmarks. I checked for 404s and added more recent entries, but this list is far from complete. New blogs, sites, tutorials and tools are released on a daily basis. Just leave a comment or contact me if you want your link(s) or [...]]]></description>
			<content:encoded><![CDATA[<p>Most of these Ruby on Rails related links are right out of my bookmarks. I checked for 404s and added more recent entries, but this list is far from complete. New blogs, sites, tutorials and tools are released on a daily basis.  Just <a href="#respond">leave a comment</a> or <a href="contact/">contact me</a> if you want your link(s) or anything related added, or have spotted any broken links.</p>
<p><em>(Updated 02/22/2008. Keep the suggestions coming!)</em></p>
<p><span id="more-46"></span></p>
<h2>Installation Guides</h2>
<p>These are to help you get Ruby and Rails installed and configured, ready for Hello World.</p>
<ul>
<li><a href="http://wiki.rubyonrails.com/rails/pages/GettingStartedWithRails">GettingStartedWithRails &#8211; A page on the official Wiki</a></li>
<li><a href="http://www.fearoffish.co.uk/ruby-on-rails-getting-started-book">Fear of Fish &#8211; Getting Started with Ruby on Rails</a></li>
<li><a href="http://digitalmediaminute.com/howto/fc4rails/">Installing Ruby on Rails with Lighttpd and MySQL on Fedora Core 4</a></li>
<li><a href="http://www.hivelogic.com/narrative/articles/ruby_rails_lighttpd_mysql_tiger?status=301">Building Ruby, Rails, LightTPD, and MySQL on Tiger</a></li>
<li><a href="http://wiki.rubyonrails.com/rails/pages/HowtosInstallation">HowtosInstallation &#8211; A page on installation, from the official Wiki</a></li>
</ul>
<h2>Freeware and Commercial Ruby on Rails IDEs and Editors</h2>
<ul>
<li><strong>Freeware IDEs</strong></li>
<li><a href="http://www.netbeans.org/features/ruby/index.html">NetBeans IDE</a> (Windows/Linux/Mac OS X/Solaris)</li>
<li><a href="http://www.aptana.org/">Aptana Studio</a> (Community Edition)</li>
<li><a href="http://www.mondrian-ide.com/">Mondrian IDE</a> (Windows/Linux)</li>
<li><a href="http://www.radrails.org/">RAD Rails</a> (now part of Aptana Studio Suite, still free)</li>
<li><a href="http://www.plasmacode.com/">RoRED</a> (Windows only at the moment)</li>
<li><a href="http://freeride.rubyforge.org/wiki/wiki.pl">FreeRIDE</a> &#8211; IDE for Ruby</li>
<li><strong>Commercial IDEs</strong></li>
<li><a href="http://www.aptana.org/">Aptana Studio</a> (Professional Edition)</li>
<li><a href="http://www.activestate.com/Products/komodo_ide/?_x=1">Komodo IDE</a> (Windows/Mac/Linux)</li>
<li><a href="http://www.ruby-ide.com/ruby/ruby_ide_and_ruby_editor.php">Arachno Ruby</a> (Windows/Linux, OS X release pending)</li>
<li><a href="http://macromates.com/">TextMate</a> (OS X only)</li>
<li><strong>Editors</strong></li>
<li><a href="http://jedit.org/">JEdit &#8211; Programmer&#8217;s Text Editor</a></li>
<li><a href="http://www.gnome.org/projects/gedit/">GEdit</a> (Official Gnome text editor)</li>
<li><a href="http://grigio.org/textmate_gedit_few_steps">Textmate-like Gedit in few steps</a></li>
<li><a href="http://www.scintilla.org/SciTE.html">SciTE</a> &#8211; A free source code editor for Win32 and X</li>
<li><a href="http://biodegradablegeek.com/2007/12/13/using-vim-as-a-complete-ruby-on-rails-ide/">Using Vim as a Complete Ruby on Rails IDE</a> (Shameless plug)</li>
<li><a href="http://ruby.about.com/od/railsvim/railsvim_Ruby_on_Rails_IDE.htm">rails.vim &#8211; Ruby on Rails IDE</a></li>
<li><a href="http://platypope.org/yada/emacs-demo/">Ruby on Rails on Emacs (video)</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/HowToUseEmacsWithRails">How To Use Emacs With Rails</a></li>
<li><strong>Extensions and everything else</strong></li>
<li><a href="http://rubyeclipse.sourceforge.net/">Ruby Development Tool (RDT)</a> Requires <a href="http://www.eclipse.org/">Eclipse</a></li>
<li><a href="http://rubyweaver.gilluminate.com/">Rubyweaver &#8211; Dreamweaver extension</a> (Compatible with MX through CS3)</li>
<li><a href="http://rails.vim.tpope.net/">Rails.vim</a> (Plugin for vi/vim/gvim/cream)</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1318">snippetsEmu</a>An attempt to emulate TextMate&#8217;s snippet expansion</li>
<li><a href="http://plugins.intellij.net/plugin/?id=1293">intellij IDEA Ruby Plugn</a> Plugin for the <a href="http://www.jetbrains.com/idea/">intellijIDEA Java IDE</a></li>
</ul>
<h2>Hello World!</h2>
<ul>
<li><a href="http://webmonkey.wired.com/webmonkey/05/28/index4a.html">Getting Your Feet Wet with Ruby on Rails</a></li>
<li><a href="http://www-128.ibm.com/developerworks/linux/library/l-rubyrails/">Fast Track Your Apps with Ruby on Rails &#8211; IBM</a></li>
<li><a href="http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html">Rolling with Ruby on Rails, Part 1</a></li>
<li><a href="http://www.onlamp.com/pub/a/onlamp/2005/03/03/rails.html">Rolling with Ruby on Rails, Part 2</a></li>
<li><a href="http://www.themolehill.com/index.php/2006/07/24/beginners-guide-setting-up-ruby-on-rails-in-windows/">Beginners Guide: Setting up Ruby on Rails in Windows</a></li>
<li><a href="http://www.themolehill.com/index.php/2006/08/14/beginners-guide-starting-with-the-model/">Beginners Guide: Starting With The Model</a></li>
<li><a href="http://wiki.rubyonrails.com/rails/pages/Tutorial">Super-quick hello world app</a></li>
<li><a href="http://www.slash7.com/articles/2005/01/24/really-getting-started-in-rails">Amy Hoy &#8211; Really Getting Started In Rails</a></li>
<li><a href="http://www.caydel.com/so-you-wanna-begin-programming-with-ruby-on-rails/"> So You Wanna Begin Programming With Ruby on Rails?</a></li>
</ul>
<h2>More In-depth Rails Tutorials</h2>
<ul>
<li><a href="http://betterexplained.com/articles/starting-ruby-on-rails-what-i-wish-i-knew/">Starting Ruby on Rails: What I Wish I Knew</a></li>
<li><a href="http://www.digitalmediaminute.com/article/1816/top-ruby-on-rails-tutorials">Top 12 Ruby on Rails Tutorials </a></li>
<li><a href="http://www.onlamp.com/pub/a/onlamp/2005/06/09/rails_ajax.html">AJAX on Rails</a></li>
<li><a href="http://www.railsforum.com/viewtopic.php?id=265">Beginning Relationships</a></li>
<li><a href="http://www.railsenvy.com/2007/8/8/activerecord-tutorial">ActiveRecord tutorial</a></li>
<li><a href="http://www.railsenvy.com/2007/2/28/rails-caching-tutorial">Rails Caching Tutorial</a></li>
<li><a href="http://www.tutorialized.com/tutorials/Ruby-on-Rails/1">Rails tutorials on Tutorialized</a></li>
<li><a href="http://www.buildingwebapps.com/articles/home">RAils tutorials at BuildingWebApps</a></li>
<li><a href="http://www.rubyrailways.com/great-ruby-on-rails-rest-resources/"> Great Ruby on Rails REST resources</a></li>
<li><a href="http://www.erikveen.dds.nl/distributingrubyapplications/rails.html">Distributing Rails Application</a></li>
<li><a href="http://thinkingrails.blogspot.com/2007/08/rails-validations.html">Rails Validations</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/04/the-complete-guide-to-rails-plugins-part-i">The Complete Guide to Rails Plugins: Part I</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/09/the-complete-guide-to-rails-plugins-part-ii">The Complete Guide to Rails Plugins: Part II</a></li>
<li><a href="http://biodegradablegeek.com/2007/12/26/understanding-basic-database-relationships-in-rails/">Understanding Basic Database Relationships in Rails</a></li>
<li><a href="http://jrhicks.net/Projects/rails/has_many_and_belongs_to_many.pdf">Has_many_and_belongs_to_many tutorial (PDF)</a></li>
</ul>
<h2>Rails Screencasts</h2>
<ul>
<li><a href="http://railscasts.com/">Railscasts</a></li>
<li><a href="http://podcast.sdruby.com/">San Diego Ruby Users Group</a></li>
<li><a href="http://coderpath.com/">Coderpath screencasts</a></li>
<li><a href="http://rails.tumblecast.com/">Rails Tumblecast</a></li>
<li><a href="http://peepcode.com/">Peepcode</a></li>
<li><a href="http://www.bestechvideos.com/tag/ruby-on-rails/">Ruby on Rails @ Best Tech Videos</a></li>
<li><a href="http://www.rubyinside.com/12-great-new-ruby-rails-screencasts-from-july-2007-566.html">10 Great New Ruby / Rails Screencasts from July 2007</a></li>
</ul>
<h2>Code Examples and Snippets</h2>
<ul>
<li><a href="http://sl33p3r.free.fr/tutorials/rails/wiki/wiki-en.html">How to build a wiki in 20 minutes (well I did not time it)</a></li>
<li><a href="http://darkhost.mine.nu:8080/~vince/rails/tutorial.html">Make a todo list program with Ruby on Rails</a></li>
<li><a href="http://tnlessone.wordpress.com/2007/01/27/how-to-make-a-simple-image-page-counter-spyer-in-20-minutes-with-rails/">How to make a simple image page counter / spyer in 20 minutes with Rails?</a></li>
<li><a href="http://rubyonrails.org/screencasts">Creating a weblog in 15 minutes (screencast)</a></li>
<li><a href="http://www.rubyinside.com/beast-an-open-source-rails-forum-in-500-lines-of-code-191.html">Beast: An open source Rails forum in under 500 lines of code</a></li>
<li><a href="http://www.petercooper.co.uk/archives/001038.html">AJAX Powered chat in 3 minutes in Ruby on Rails</a></li>
<li><a href="http://workingwithrails.com/browse/projects">Working With Rails Projects</a></li>
<li><a href="http://workingwithrails.com/browse/code">Working With Rails Code</a></li>
<li><a href="http://textsnippets.com/tag/rails">Text Snippets</a></li>
<li><a href="http://rubyforge.org/snippet/browse.php?by=lang&amp;lang=17">Snippets at Rubyforge</a></li>
<li><a href="http://snippets.dzone.com/tag/rails">DZone Rails snippets</a></li>
</ul>
<h2>Ruby / Rails Blogs</h2>
<p>These are blogs dedicated primarily to Ruby and/or Rails.</p>
<ul>
<li><a href="http://railsenvy.com/">Rails Envy</a></li>
<li><a href="http://nubyonrails.com/">nor &#8211; Nuby on Rails</a></li>
<li><a href="http://www.rubyinside.com/">Ruby Inside</a></li>
<li><a href="http://www.sameshirteveryday.com/">Same Shirt Everyday</a></li>
<li><a href="http://www.rubynoob.com/">Rubynoob</a></li>
<li><a href="http://antoniocangiano.com/">Zen and the Art of Ruby Programming</a></li>
<li><strong><a href="http://www.rorsecurity.info/">Ruby on Rails security</a></strong></li>
<li><a href="http://www.realityforge.org/">Reality Forge</a></li>
<li><a href="http://glu.ttono.us/">Gluttonous</a></li>
<li><a href="http://thinkingrails.blogspot.com">Thinking Rails</a></li>
<li><a href="http://www.seoonrails.com/">SEO On Rails</a></li>
<li><a href="http://www.notsostupid.com/">Not So Stupid</a></li>
<li><a href="http://blog.mondragon.cc/">Mike Mondragon</a></li>
<li><a href="http://www.akitaonrails.com/">Akita on Rails</a></li>
<li><a href="http://railsjitsu.com">Railsjitsu</a></li>
<li><a href="http://blog.jayfields.com/">Jay Fields Thoughts</a></li>
<li><a href="http://www.aidanf.net/rails">Aidanf</a></li>
<li><a href="http://www.railsonwave.com/">Rails on Wave</a></li>
<li><a href="http://kurt.karmalab.org/articles/category/ruby"></a></li>
<li><a href="http://railsontherun.com/">Rails on the Run</a></li>
<li><a href="http://workingwithrails.com/browse/popular/people">Popular People on Working With Rails (WWR)</a></li>
<li><a href="http://kurt.karmalab.org/articles/category/ruby">Schrade.Blog &#8211; Tech and Business Ramblings by Kurt Schrader</a></li>
<li><a href="http://grasprubyonrails.com/">Grasp Ruby on Rails</a></li>
<li><a href="http://www.rubyrailways.com/">Ruby Railways</a></li>
<li><a href="http://www.onrails.org/articles/category/ruby-on-rails">OnRails.og &#8211; Ruby On Rails and related matters.</a></li>
<li><a href="http://www.softiesonrails.com/">Softies On Rails</a></li>
<li><a href="http://www.multiply.org/notebook/">Notebook</a></li>
</ul>
<h2>Communities / Wikis / Forums / Mailing lists / IRC</h2>
<ul>
<li><a href="http://www.rubyonrails.org/community">Official Rails community page</a></li>
<li><a href="http://www.railsforum.com/">Rails Forum</a></li>
<li><a href="http://wiki.rubyonrails.org/rails">Ruby on Rails Wiki</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/IRC">#RubyOnRails on the Freenode IRC network</a></li>
<li><a href="http://www.ruby-forum.com/">Ruby-forum</a></li>
</ul>
<h2>Gems / Plugins / Tools</h2>
<p>These are some miscellaneous Rails stuff I had bookmarked. I know there are hundreds of great things I&#8217;m missing here. Don&#8217;t hesitate to recommend your favorites.</p>
<ul>
<li><a href="http://www.railsify.com/">Railsify (directory of plugins)</a></li>
<li><a href="http://www.activescaffold.com/">ActiveScaffold</a></li>
<li><a href="http://haml.hamptoncatlin.com/">#Haml</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/LoginGenerator">LoginGenerator</a></li>
<li><a href="http://www.zenspider.com/ZSS/Products/ZenTest/">ZenTest &#8211; Testing on steroids</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/Plugins">Plugins (official RoR wiki page)</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/04/the-complete-guide-to-rails-plugins-part-i">The Complete Guide to Rails Plugins: Part I</a></li>
<li><a href="http://nubyonrails.com/articles/2006/05/09/the-complete-guide-to-rails-plugins-part-ii">The Complete Guide to Rails Plugins: Part II</a></li>
</ul>
<h2>Rails 2.0</h2>
<ul>
<li><a href="http://www.akitaonrails.com/2007/12/12/rolling-with-rails-2-0-the-first-full-tutorial">Rolling with Rails 2.0 &#8211; The First Full Tutorial</a></li>
<li><a href="http://mislav.caboo.se/rails/rails-2-0-taking-the-plunge/">Rails 2.0: taking the plunge (with script that checks if your apps are rails2 compliant)</a></li>
<li><a href="http://www.randomsyntax.com/2008/01/10/getting-started-with-ruby-on-rails-2-making-a-link-manager-part-1/">Getting Started with Ruby on Rails 2: Making a Link Manager (Part 1)</a></li>
<li><a href="http://mentalized.net/journal/2007/03/13/rails_20_deprecations/">Rails 2.0 deprecations</a></li>
<li><a href="http://softiesonrails.com/2007/7/11/upgrading-your-views-to-rails-2-0">Upgrading your views to Rails 2.0</a></li>
<li><a href="http://assertbuggy.blogspot.com/2007/10/how-to-upgrade-ruby-on-rails-restful.html">How to upgrade Ruby on Rails Restful routes to 2.0</a></li>
<li><a href="http://www.railsontherun.com/2007/12/17/rails-2-0-2-with-few-changes">Rails 2.0.2 with few changes</a></li>
<li><a href="http://blog.codefront.net/2007/12/17/rails-202-released-so-whats-new/">Rails 2.0.2 released, so what’s new?</a></li>
<li><a href="http://www.infoq.com/articles/ruby20-dhh-interview">Talking Rails 2.0 with David Heinemeier Hansson</a></li>
<li><a href="http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done">Rails 2.0: It&#8217;s done!</a></li>
</ul>
<h2>Free Ruby / Rails Books</h2>
<p>These are books that you can read online or download for free.</p>
<ul>
<li><a href="http://poignantguide.net/ruby/">Why&#8217;s (poignant) guide to ruby</a></li>
<li><a href="http://en.wikibooks.org/wiki/Ruby_Programming">Ruby Programming (Wikibooks.org)</a></li>
<li><a href="http://media.sitepoint.com/books/ror.pdf">(PDF) Build Your Own Ruby on Rails Web Applications by Patrick Lenz (provided by Sitepoint.com)</a></li>
<li><a href="http://rails.homelinux.org/">Four days on Rails</a></li>
<li><a href="http://manuals.rubyonrails.com/">Rubyonrails.com shelf (helpful manuals)</a></li>
</ul>
<h2>References / Cheatsheets</h2>
<p>Handy references and cheat sheets to bookmark or print out.</p>
<ul>
<li><a href="http://www.railsapi.org/">RailsAPI.org &#8211; PHP.net style documentation for Rails</a></li>
<li><a href="http://noobkit.com/">Noobkit (great Rails doc)</a></li>
<li><a href="http://www.ilovejackdaniels.com/cheat-sheets/ruby-on-rails-cheat-sheet/">Ruby on Rails Cheatsheet</a></li>
<li><a href="http://www.rorsecurity.info/ruby-on-rails-security-cheatsheet/">Rails Security Cheatsheet</a></li>
<li><a href="http://garrettsnider.backpackit.com/pub/367902">Rails Migration Cheat Sheet</a></li>
<li><a href="http://topfunky.com/clients/peepcode/REST-cheatsheet.pdf">REST Cheatsheet (PDF)</a></li>
<li><a href="http://blog.invisible.ch/2006/05/01/ruby-on-rails-reference/">Ruby on Rails reference</a></li>
<li><a href="http://blogs.tech-recipes.com/johnny/rails-quick-reference/">Ruby on Rails quick reference</a></li>
<li><a href="http://topfunky.com/clients/rails/ruby_and_rails_assertions.pdf">Rails Test Assertions (PDF)</a></li>
<li><a href="http://railshandbook.com/">Railshandbook, another big collection of links</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2008/01/expanding-list-of-ruby-on-rails-sites-editors-tutorials-cheat-sheets-and-more/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Understanding Basic Database Relationships in Rails</title>
		<link>http://biodegradablegeek.com/2007/12/understanding-basic-database-relationships-in-rails/</link>
		<comments>http://biodegradablegeek.com/2007/12/understanding-basic-database-relationships-in-rails/#comments</comments>
		<pubDate>Thu, 27 Dec 2007 02:01:15 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[database relationships]]></category>
		<category><![CDATA[migrations]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2007/12/26/understanding-basic-database-relationships-in-rails/</guid>
		<description><![CDATA[This short tutorial will be beneficial for you if database relationships and keywords like belongs_to and has_many confuse you, or if you&#8217;re trying to find out how relationships are implemented in Rails. As we create a small demonstration project, you&#8217;ll see that one beauty of Rails is how it does most of the work gluing [...]]]></description>
			<content:encoded><![CDATA[<p><img src='/wp-content/uploads/2007/12/keke_nixon_erd.jpg' alt="keke nixon erd Understanding Basic Database Relationships in Rails" align="left" title="Understanding Basic Database Relationships in Rails" /></p>
<p>This <i>short</i> tutorial will be beneficial for you if database relationships and keywords like belongs_to and has_many confuse you, or if you&#8217;re trying to find out how relationships are implemented in Rails. As we create a small demonstration project, you&#8217;ll see that one beauty of Rails is how it does most of the work gluing everything together, after you&#8217;ve supplied it with information about your database&#8217;s structure.</p>
<p>But first &#8212; why bother learning about relationships? Very simply, they eliminate a major problem called an update anomaly, and they will probably save you disk space. Having info repeated in multiple entries can be problematic. How would you update a mass misspelling? Would you even notice a misspelled entry? <a href="http://en.wikipedia.org/wiki/Database_normalization">Database normalization</a> and multiple intertwined tables (via relationships) can curb this problem. Fortunately, ActiveRecord makes this easy.</p>
<p>For example, if you store the name and location of all your users in the same database table, you might be wasting disk space by having the same information repeated in multiple entries. You would be wasting a lot of space if your clam-cake-vendor-review site has hundreds of users living in &#8220;the State of Rhode Island and Providence Plantations.&#8221; This can be eliminated by having the locations tied to unique IDs in their own table, and associated to a user by their ID. This also makes renaming a location easy. Changing &#8220;the State of Rhode Island and Providence Plantations&#8221; to &#8220;Ocean State&#8221; is only done in one location, once.</p>
<p>Rather than going over all possible types of relationships here, I will be covering the very basics; Enough to help you grasp the main idea and see how it is implemented in Rails. Let&#8217;s begin by designing a simple project.<br />
<span id="more-44"></span></p>
<h3>Project Description</h3>
<p>Let&#8217;s design a basic musician database. Each artist will be one individual with a name, age, and list of songs (not albums). Each song will have a title, duration and fit under one genre. This design is overly simplified and far from realistic. For simplicity&#8217;s sake, we are ignoring the fact that an artist may consist of several individuals and may have multiple albums containing multiple songs, and each song, artist and album can fit under a mesh of genres. It might have a tough time competing with MusicBrainz or Last.fm, but it should be sufficient enough for our purpose.</p>
<h2>Go Go Go</h2>
<p>Ruby on Rails and your database software (I use MySQL, but SQLite/PostgreSQL work fine) should be installed and functional. For help installing Rails, see <a href="http://www.rubyonrails.org/down">the official site</a> and <a href="http://wiki.rubyonrails.org/rails/pages/GettingStartedWithRails">the official Wiki</a>.</p>
<p><i>(If using an editor such as <a href="/2007/12/13/using-vim-as-a-complete-ruby-on-rails-ide/">vim with rails.vim</a>, you may substitute those commands and shortcuts for the console commands I use here)</i></p>
<p>In the directory you want your project to reside, create a Rails framework named themusic:</p>
<pre lang="bash" line="1">
$ rails themusic
    create
    create app/controllers
    create app/helpers
    create app/models
    create app/views/layouts
    create app/environments
    ... omitted ...
</pre>
<p>Head into the newly created <i>themusic</i> directory and open config/database.yml using your <a href="http://www.vim.org">favorite text editor</a>. This file tells Rails what database software you&#8217;re using and how it can access it. Notice that this file is divided into three parts (environments): Development, test and production. Rails has the ability to use different databases and even database software for each environment. We will stick in the development environment.</p>
<p>In development, any changes you make to the code are immediate &#8211; not requiring a server restart to take effect &#8211; and errors spit out a detailed stack trace. The trade off? Performance takes a hit.</p>
<p>Fill in your database login information (you&#8217;ll likely just have to put in your password) before saving and closing the file. Create a new database named themusic_development. I use <a href="http://phpmyadmin.net">PHPMyAdmin</a>, but this can be done in MySQL using the commandline:</p>
<pre lang="text" line="1">
<pre>
$ mysql -u username -h localhost -p
Enter password: (type pass and hit Enter)
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1984

mysql> CREATE DATABASE themusic_development;
Query OK, 1 row affected (0.04 sec)</pre>
</pre>
<h2>Identifying Entities and Attributes</h2>
<p>An entity is any object you are required to keep information on. Examples of entities include customers, orders, departments and items. How many entities are we keeping track of in our example app? Three: Artist, song and genre. Keep in mind that things you don&#8217;t need to store data on are not entities. If your business doesn&#8217;t require that you keep track of user or customer information, then they don&#8217;t have to be entities. Identifying entities isn&#8217;t always straightforward, and it&#8217;s not uncommon to alter your app after the initial design phase, so don&#8217;t sweat this too much right now; Just follow along.</p>
<p>Each entity has attributes. A person entity might have attributes such as name and DOB. If we were writing a stock inventory system, each item entity might have a price, manufacturer, description, and so forth. In our example, we have the following entities and attributes:</p>
<ul>
<li>Artist: Has a name, age and songs.</li>
<li>Song: Has a title, duration and fits under one artist and one genre.</li>
<li>Genre: Each has a name, and houses many songs.</li>
</ul>
<p>Here&#8217;s an aesthetic entity-relationship diagram (ERD) depicting this. A crow&#8217;s foot line is a &#8220;has_many&#8221; relationship. (You can read it going in both directions as: An artist has many songs, a song belongs to an artist):<br />
<img src='http://biodegradablegeek.com/wp-content/uploads/2007/12/erd_understanding_relationships1.gif' alt="erd understanding relationships1 Understanding Basic Database Relationships in Rails"  title="Understanding Basic Database Relationships in Rails" /><br />
Also note sexy 60&#8242;s font.</p>
<h2>Generating the Models and Setting Up the Migrations and Relationships</h2>
<p>We have defined our entities and their relationships on paper, and now need them implemented in Rails. Let&#8217;s generate three models representing our entities:</p>
<pre lang="bash" line="1">
$ ruby script/generate model Artist
$ ruby script/generate model Song
$ ruby script/generate model Genre
</pre>
<p>The generate script automatically creates a migration for each model.</p>
<p>Migrations are optional but immensely helpful (and awesome). If you have no clue what I&#8217;m talking about, see <a  href="http://wiki.rubyonrails.org/rails/pages/UnderstandingMigrations">UnderstandingMigrations</a> and <a  href="http://glu.ttono.us/articles/2005/10/27/the-joy-of-migrations">the joy of migrations</a>.</p>
<p>Let&#8217;s edit each migration to create the appropriate fields for each table.</p>
<p><i>(Although not advised, you may use the MySQL console to create the tables and columns instead of using migrations and rake)</i></p>
<h3>Table structure</h3>
<p>The artist table will have the following fields:</p>
<ul>
<li>Unique ID: Created automatically by Rails; We don&#8217;t need this in the migration file.</li>
<li>Name: a string</li>
<li>Age: a small integer</li>
</ul>
<p>Open up the Artist model&#8217;s migration file (db/migrate/001_create_artists.rb) and edit it to resemble this:</p>
<pre lang="rails" line="1">
class CreateArtists < ActiveRecord::Migration
  def self.up
    create_table :artists do |t|
      t.column :name, :string
      t.column :age, :integer
    end
  end

  def self.down
    drop_table :artists
  end
end
</pre>
<p>The song table will have the following fields:</p>
<ul>
<li>Title: a string</li>
<li>Duration in seconds: an integer</li>
<li>Artist: Identified by the artist's unique ID (integer and cannot be NULL)</li>
<li>Genre: Identified by the genre's unique ID (as above, a NON-NULL integer)</li>
</ul>
<p>Edit the Song migration (db/migrate/002_create_songs.rb):</p>
<pre lang="rails" line="1">
class CreateSongs < ActiveRecord::Migration
  def self.up
    create_table :songs do |t|
      t.column :title, :string
      t.column :duration, :integer
      t.column :artist_id, :integer, :null => false
      t.column :genre_id, :integer, :null => false
    end
  end

  def self.down
    drop_table :songs
  end
end
</pre>
<p>The genre table will have a name field. Edit that migration (db/migrations/003_create_genres.rb):</p>
<pre lang="rails" line="1">
class CreateGenres < ActiveRecord::Migration
  def self.up
    create_table :genres do |t|
      t.column :name, :string
    end
  end

  def self.down
    drop_table :genres
  end
end
</pre>
<p>Use Rake to apply the migrations to your database. If all goes well, your console should display something like this:</p>
<pre lang="bash" line="1">
$ rake db:migrate
(in /home/lotus/rails/themusic)
== CreateArtists: migrating ====================
-- create_table(:artists)
   -> 0.0896s
== CreateArtists: migrated (0.0897s) ==============

== CreateSongs: migrating ======================
-- create_table(:songs)
   -> 0.0263s
== CreateSongs: migrated (0.0264s) ================

== CreateGenres: migrating =================
-- create_table(:genres)
   -> 0.0350s
== CreateGenres: migrated (0.0351s) ===========
</pre>
<h3>Relationships</h3>
<p>Rails needs to know how your models are related. We already did this in the design phase earlier above, but we now need to translate it into terms Rails can understand. Each artist will have multiple songs; Rails understands this using the keyword <i>has_many</i>. Edit the artist model (app/models/artist.rb) to look like this (notice that :songs is plural):</p>
<pre lang="rails" line="1">
class Artist < ActiveRecord::Base
  has_many :songs
end
</pre>
<p>This association is pretty self-explanatory when spoken aloud: Artist has many Songs.</p>
<p>Each song will belong to one artist and one genre. In the migration, we specifically defined that artist_id and genre_id must exist, they cannot not be NULL. This means a song <strong>must</strong> belong to an artist <i>and</i> fit under a genre.</p>
<p>Edit song.rb (notice both params supplied to belongs_to are singular):</p>
<pre lang="rails" line="1">
class Song < ActiveRecord::Base
  belongs_to :artist
  belongs_to :genre
end
</pre>
<p>We can have multiple songs under the same genre. This is a has_many association. Add it to genre.rb:</p>
<pre lang="rails" line="1">
class Genre < ActiveRecord::Base
  has_many :songs
end
</pre>
<h2>Interacting with Our App Via Console</h2>
<p>Instead of creating a web interface or editing scaffolds, let's use the Rails console to interact with our application in its current state. The Rails console is a script named 'console' in our apps' script directory. This console gives you low level access to your Ruby on Rails application, which it loads on its own. It's a powerful debugger, and makes it fast and easy to test out individual components in your program -- not to mention it's fun! It isn't always practical but suffices perfectly for our purposes now.</p>
<p>Fire it up: ruby script/console.  You should get a >> prompt.</p>
<p>The console includes tab-completion (for example, press Artist.f<tab><tab> for a list of commands beginning with the letter f), so feel free to poke around and experiment.</p>
<p>Let's begin by creating an instance of the Artist model. Type the following and hit enter.</p>
<pre lang="rails" line="1">
>> jb = Artist.new(:name => 'Joe Bloggs', :age => 36)
</pre>
<p>We have essentially created a new record in our database, but if you check your artist's table in the database now, you'll notice that this entry is non-existent. This is because it only exists in memory at this point. We have not saved it. It doesn't have a unique ID associated with it. The <i>new_record?</i> method returns true if the model has never been saved. You can access an object's methods and attributes via the console:</p>
<pre lang="rails" line="1">
>> jb.new_record?
=> true
>> jb.name
=> "Joe Bloggs"
>> jb.age
=> 36
>> jb.id
=> nil
</pre>
<p>Now try this:</p>
<pre lang="rails" line="1">
>> jb.songs
=> []
</pre>
<p>WTFMATEOMGMAGIC! []!? An empty array? Do you remember adding a songs attribute? I hope not, 'cause you didn't! Rails knows that an Artist object can have multiple songs because you defined this association in the Artist model as 'has_many :songs.' Each song the artist has will be added to this array.</p>
<p>Notice that the record gets an ID after it is saved:</p>
<pre lang="rails" line="1">
>> jb.save
=> true
>> jb.id
=> 1
</pre>
<p>Save returns <i>true</i> on success. Let's create a Song instance:</p>
<pre lang="rails" line="1">
>> tune = Song.new(:title => 'Love Me Three Times', :duration => 456)
=> #<song:0x2b420d56ec00 @attributes={"artist_id"=>nil, "title"=>"Love Me Three Times", "genre_id"=>nil, "duration"=>456}, @new_record=true>
</pre>
<p>Trying to save our song as this point gives us errors:</p>
<pre lang="Rails" line="1">
>> tune.save
ActiveRecord::StatementInvalid: Mysql::Error: Column 'artist_id' cannot be null:
... long trace omitted ...
</pre>
<p>Remember that artist_id and genre_id cannot be left nil. Let's create some genres on the fly. In practice, this should be done in a migration.</p>
<pre lang="rails" line="1">
>> Genre.new(:name => 'Bluegrass').save
=> true
>> Genre.new(:name => 'Goa Trance').save
=> true
>> Genre.new(:name => 'Doo Wop').save
=> true
>> Genre.new(:name => 'Blues Rock').save
=> true
>> Genre.new(:name => 'Emo').save
=> true
</pre>
<p>Assign the tune a genre:</p>
<pre lang="rails" line="1">
>> tune.genre = Genre.find_by_name('Blues Rock')
</pre>
<p>See that it has been set (don't worry if your ID differs):</p>
<pre lang="rails" line="1">
>> tune.genre.name
=> "Blues Rock"
>> tune.genre_id
=> 4
</pre>
<p>Use the Array object's << operand to append to Joe Blogg's song array and then save it.</p>
<pre lang="rails" line="1">
>> jb.songs << tune
>> tune.save
=> true
</pre>
<p>Exploration:</p>
<pre lang="rails" line="1">
>> jb.songs[0].title
=> "Love Me Three Times"
>> tune.artist.name
=> "Joe Bloggs"
>> tune.artist_id
=> 1
</pre>
<p>Let's fetch and create an instance of Joe Blogg's record from the database:</p>
<pre lang="rails" line="1">
>> bloggs = Artist.find_by_name('Joe Bloggs')
</pre>
<p>Let's explore this object further:</p>
<pre lang="rails" line="1">
>> bloggs.name
=> "Joe Bloggs"
>> bloggs.songs[0].title
=> "Love Me Three Times"
>> bloggs.songs[0].genre.name
=> "Blues Rock"
</pre>
<p>Add a few more artists and songs to the database and then close the console (ctrl+D or type "quit").</p>
<p>In the Songs table in our database, the genre and artist are stored by ID as opposed to by string. Even if we have a centillion songs by one artist, updating that artist's info is only done in one place, once - in the record associated with that ID. If Joe Bloggs changes his name to "The Artist Formerly Known As Joe Bloggs," we only need to change this once, and it will take effect throughout our app.</p>
<h2>Creating a Browser Interface</h2>
<p>Don't get stoned (on beer) just yet. You have a basic understanding of why relationships are useful and how they work, but it's unlikely your application will be restricted to the Rails console. Let's create a very basic (and hideous) web interface for our music application. Each objective will be followed by details and caveats on its implementation.</p>
<p>We have models, but we also need controllers and views. Controllers handle events from the user, fetch data from models, and generate the output (view) that our users will see and interact with. This is known as the <a href="http://en.wikipedia.org/wiki/Model-view-controller">MVC architecture</a>.</p>
<p>By convention, a controller's name is plural as opposed to a model which is singular. For example: StoriesController, PicturesController, PeopleController, etcetra; Rails adds the 'Controller' suffix to the name you give the generate script. Memorizing Rails' naming conventions can be confusing at first. I advise keeping the <a href="http://nubyonrails.com/tools/pluralize/">excellent pluralize tool</a> on hand.</p>
<h3>Objective #1</h3>
<p>When the user visits http://domain.cxm/artists, we want them greeted with a list of the artists in our database. Clicking an artist's name will open a page with that artist's personal info and list of songs.</p>
<p>Use the following code to generate the first controller:</p>
<pre lang="bash" line="1">
$ ruby script/generate controller Artists
</pre>
<p>The index view (what the user will see) needs to have a list of artists from the database. Add the following index method to the new controller in app/controllers/artists_controller.rb:</p>
<pre lang="rails" line="1">
class ArtistsController < ApplicationController
    def index
        @artists = Artist.find(:all)
    end
end
</pre>
<p>find(:all) returns all the records in the Artists table. Create the view file app/views/artists/index.rhtml and add the following to it:</p>
<pre lang="rails" line="1">
<h1>The Music Just Turns Me On</h1>
<h2>Available artists</h2>
<ul>
<% @artists.each do |artist| %>
<li><%= link_to artist.name, :action => 'details', :id => artist.id %></li>

<% end %>
</ul>
</pre>
<p>Fire up the server script ($ ruby script/server) and point your browser to <a href="http://localhost:3000/artists" target="_blank">http://localhost:3000/artists</a>. This is the default address for a rails application. If all is well with the world, you'll see this in your browser:</p>
<h1 style="color:black;">The Music Just Turns Me On</h1>
<h2 style="color:black;">Available artists</h2>
<ul>
<li><a href="http://localhost:3000/artists/details/1" target="_blank">Joe Bloggs</a></li>
</ul>
<p>In my example I only have one artist; More would better illustrate the code, particularly later below. Clicking on an artist's name will lead to an "Unknown action" error, as we do not yet have a <i>details</i> method in our ArtistsController. Let's add that to our controller now:</p>
<pre lang="rails" line="1">
def details
    @artist = Artist.find_by_id(params[:id])
    @songs = @artist.songs
end
</pre>
<p>The details.rhtml view (create it in the same dir as the index view) should look like this:</p>
<pre lang="rails" line="1">
<h1><%= @artist.name %> (<%= @artist.age %>)</h1>
<ol>
    <% @songs.each do |song| %>
<li><%= song.title %> <%= song.duration %> -- <%= song.genre.name %></li>

    <% end %>
</ol>
</pre>
<p>Refresh (or run the server again if you closed it) and click an artist's name in your browser to see the details view:</p>
<h3 style="color:black;">Joe bloggs (36)</h3>
<ol>
<li>Love Me Three Times 456 -- Blues Rock</li>
</ol>
<p>456 is the duration in seconds; Appropriate for storage, but will bring us terrible misfortune from the marketing department. Let's make it user-friendly in the form of minutes:seconds. Change the songs.each loop above to the following:</p>
<pre lang="rails" line="1">
<ol>
<% @songs.each do |song| %>
    <%
        min = song.duration / 60
        sec = song.duration % 60
        @duration = '%d:%.2d' % [min, sec]
    %>
<li><%= song.title %> <%= @duration %> -- <%= song.genre.name %></li>

<% end %>
</ol>
</pre>
<p>Check it in your browser:</p>
<h3 style="color:black;">Joe bloggs (36)</h3>
<ol>
<li>Love Me Three Times 7:36 -- Blues Rock</li>
</ol>
<p>Purty!</p>
<h3>Objective #2</h3>
<p>Users should be able to browse via genre. Clicking 'Blues Rock' should list every Blues Rock song from every artist in the database; Let's make this happen.</p>
<p>First, we will make the song genres on the Artist details page links leading to a method called 'browse' in a not-yet-existent genres controller.</p>
<p>In details.rhtml, change the &gt;li&lt; ... &gt;/li&lt; line to reflect the following:</p>
<pre lang="rails" line="1">
<li><%= song.title %> <%= @duration %> --
        <%= link_to song.genre.name, :controller => 'genres', :action => 'browse', :id => song.genre.id %></li>
</pre>
<p>Let's generate that controller and implement two methods.</p>
<pre lang="bash" line="1">
$ ruby script/generate controller Genres index browse
</pre>
<p>Open app/controllers/genres_controller.rb. We have two method skeletons: index and browse. To the browse method's body, we want to add code that does this:</p>
<p>Psuedo-code:</p>
<pre>
<pre lang="text" line="1">
if an ID was specified
    Fetch the specific genre record associated with that ID
else
    Redirect user to genre index view (which will have a list of available genres)
</pre>
</pre>
<p>Here's the Ruby code, add it to the controller:</p>
<pre lang="rails" line="1">
if params.include? :id
    @genre = Genre.find(:first, :conditions => ['id = ?', params[:id]])
else
    redirect_to :action => 'index'
end
</pre>
<p>The find() returns the first (and only, as each genre should be unique) record matching the ID that was passed from the previous page. You can swap that find method with the simpler and easier to read Genre.find_by_id(params[:id]) if you wish.</p>
<p>Generate created an index view and a browse view for us because we passed it the method names when generating the GenresController. Open browse.rhtml, delete the placeholder HTML inside and add the following:</p>
<pre lang="rails" line="1">
<h1>Available <%= @genre.name %> songs</h1>
<ol>
<% @genre.songs.each do |song| %>
    <%
        min = song.duration / 60
        sec = song.duration % 60
        @duration = '%d:%.2d' % [min, sec]
    %>
<li><%= link_to song.artist.name, :controller => 'artists', :action => 'details', :id => song.artist.id %> - <%= song.title %> (<%= @duration %>)</li>

<% end %>
</ol>
</pre>
<p>Notice the blatant violation of Ruby on Rail's fundamental <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">Don't Repeat Yourself (DRY)</a> principle. Having the same code <a href="http://en.wikipedia.org/wiki/Cut_and_paste_programming">pasted</a> in more than one place is, among other things, sloppy programming. I only did this here because I don't want to violate the <a href="http://en.wikipedia.org/wiki/KISS_principle">KISS</a> principle. In your real apps, use partials, applications.rb and the application controller to maximize <a href="http://en.wikipedia.org/wiki/Code_reuse">Code Reuse</a>!</p>
<p>Point your browser to an artist's page and click a genre:</p>
<h1 style="color:black;">Available Blues Rock songs</h1>
<ol>
<li><a href="http://localhost:3000/artists/details/1" target="_blank">Joe Bloggs</a> - Love Me Three Times (7:36)</li>
</ol>
<p>The user should also be able to browse by all the available genres in the database. The app/views/genres/index.rhtml view (not to be confused with the ArtistController method's index view) needs a list of genres. Add the following code into the GenresController's index method:</p>
<pre lang="rails" line="1">
@genres = Genre.find(:all)
</pre>
<p>and the following in the genres/index.rhtml view (delete placeholder HTML, if any):</p>
<pre lang="rails" line="1">
<h1>Browse by genre</h1>
<ul>
    <% @genres.each do |cat| %>
<li><%= link_to cat.name, :action => :browse, :id => cat.id %></li>

    <% end %>
</ul>
</pre>
<p>Hit up <a href="http://localhost:3000/genres/">http://localhost:3000/genres/</a>:</p>
<h1 style="color:black;">Browse by genre</h1>
<ul>
<li><a href="http://localhost:3000/genres/browse/1">Bluegrass</a></li>
<li><a href="http://localhost:3000/genres/browse/2">Goa Trance</a></li>
<li><a href="http://localhost:3000/genres/browse/3">Doo Wop</a></li>
<li><a href="http://localhost:3000/genres/browse/4">Blues Rock</a></li>
<li><a href="http://localhost:3000/genres/browse/5">Emo</a></li>
</ul>
<h3>Objective #3</h3>
<p>Give the user the ability to add artists and songs via forms.</p>
<p>Open app/views/artists/index.rhtml and add the following form_tag code right below the h1 header:</p>
<pre lang="rails" line="1">
<!-- Form to add a new artist -->
<% form_tag :action => :new do %>
    Name: <%= text_field :artist, :name %>
    Age: <%= text_field :artist, :age, :size => 1 %>
    <%= submit_tag 'Add new artist' %>
<% end %>
</pre>
<p>This snippet creates a form with three elements. A name textbox, an age textbox, and a submit button. ':action => :new' tells the form to direct the user's input to the ArtistController's <i>new</i> method. Open app/controllers/artists_controller.rb and add this <i>new</i> method now:</p>
<pre lang="rails" line="1">
def new
    @newartist = params[:artist]
    Artist.new(@newartist).save
    redirect_to :action => :index
end
</pre>
<p>Here's a brief overview of how this function works:</p>
<p><strong>Line 1: What is params[:artist]?</strong></p>
<p>I won't go over <a href="http://weblog.rubyonrails.org/2006/4/25/use-params-not-params">params</a> nor <a href="http://www.rubynoob.com/articles/2007/7/9/forms-in-ruby-on-rails_part_1">forms</a> too thoroughly here. Above in our view, we had "text_field :artist, :name" and "text_field :artist, :age" -- The first parameter we passed to both, ':artist,' is the object name. Rails generates a hash with that name and puts each input field's name (that's the second part we passed the two text_fields, ':name' and :'age' respectively) as a key in that hash. The value that key corresponds to is what the user inputed on the form. For example, if we have a form asking the user to tell us about his car:</p>
<ul>
<li>text_field :car, :model</li>
<li>text_field :car, :make</li>
<li>text_field :car, :year</li>
</ul>
<p>where the form's :action parameter points to method :vroom. In the vroom method, we'd have a hash named ':car' available in params (params[:car]). This hash will have three key-value pairs: params[:car][:model], params[:car][:make] and params[:car][:year]. The values of each will be whatever the user provided in the form's text fields.</p>
<p><strong>Line 2: Why are we passing params[:artist] to the Artist constructor (Artist.new)?</strong></p>
<p>We need to create a new Artist record in the database. We do so like this: Artist.new(:name => 'whatever', :age => 123). Artist.new accepts a hash with the keys :name and :age. @newartist is a hash with both those keys, because that's what we named our text_fields in the form above. It might be easier to understand knowing we can do this:</p>
<pre lang="rails" line="1">
Artist.new(:name => @newartist[:name], :age => @newartist[:age]); Artist.save
</pre>
<p>@newartist is optional. We can pass params[:artist] directly to Artist.new. In the real world you'd want to check ALL input coming from the user before any further processing.</p>
<p><strong>Line 3: Why are we redirecting to the index method?</strong></p>
<p>By default, Rails would have tried to give the user the new.rhtml view, resulting in an error (we don't have such a view). We override this behavior by redirecting flow to the index method. The index method runs its course and the user is then served the index.rhtml view. In practice, this means the user is taken to the front page after they click the submit button.</p>
<p>After the changes above, this is what the artist form should now look like:</p>
<h1 style="color:black;">The Music Just Turns Me On</h1>
<p>Name:<br />
<input type="text"/><br/><br />
Age:<br />
<input type="text" size="1"/></p>
<input type="submit" value="Add new artist">
<h2 style="color:black;">Available artists</h2>
<p>... HTML output omitted ...</p>
<p>On the artist details page, let's implement the ability to add a new song via a form_tag. We need a list of available genres dynamically generated from the database available to the details.rhtml view. This will go into the ArtistController's details method:</p>
<pre lang="rails" line="1">
  def details
    @artist = Artist.find_by_id(params[:id])
    @songs = @artist.songs
    @genres = Genre.find(:all)
  end
</pre>
<p>Open the details.rhtml view and add the following right under the header:</p>
<pre lang="rails" line="1">
<% form_tag :action => :addsong, :id => @artist.id do %>
    Title: <%= text_field :song, :title %>
    Duration (seconds): <%= text_field :song, :duration, :size => 3 %>
    
    <% @genres.each do |cat| %>
        <%= radio_button :song, :genre_id, cat.id %><%= cat.name %>
    <% end %>
    <%= submit_tag 'Add song' %>
<% end %>
</pre>
<p>This form will have a title and duration textfield, <i>N</i>(in this example, 5) genre radio buttons and a submit button. The radio_button helper accepts an object name (:song), an attribute name (in this case :genre_id, which can be accessed as params[:song].genre_id) and a tag value for that option (in our case, the numerical ID of the genre). We pass :id to the form_tag helper because we need it to lookup the artist record in the :addsong method, which we will now create. Open artists_controller.rb and add the following in the class body:</p>
<pre lang="rails" line="1">
def addsong
    # Create new song
    @song = Song.new(params[:song])

    # Find artist and append new song to his current array of songs
    @artist = Artist.find_by_id(params[:id])
    @artist.songs << @song
    @song.save

    redirect_to :action => 'details', :id => params[:id]
end
</pre>
<p>Save. Run server script. Be amazed -- Unless it doesn't work; In which case compare your code with mine and make sure there are no typos, paying attention to nested brackets and colons.</p>
<h1 style="color:black;">The Music Just Turns Me On</h1>
<p>Title:<br />
<input id="song_title" name="song[title]" size="30" type="text" />
Duration (seconds):<br />
<input id="song_duration" name="song[duration]" size="3" type="text" /></p>
<input id="song_genre_id_1" name="song[genre_id]" type="radio" value="1" />Bluegrass</p>
<input id="song_genre_id_2" name="song[genre_id]" type="radio" value="2" />Goa Trance</p>
<input id="song_genre_id_3" name="song[genre_id]" type="radio" value="3" />Doo Wop</p>
<input id="song_genre_id_4" name="song[genre_id]" type="radio" value="4" />Emo</p>
<input id="song_genre_id_5" name="song[genre_id]" type="radio" value="5" />Blues rock</p>
<input name="commit" type="submit" value="Add song" />
<h2 style="color:black;">Available artists</h2>
<p>... HTML output omitted ...</p>
<h2>Deleting Records: Remember Josh Breckman</h2>
<p>Be cautious if you attempt to implement functionality to delete records. Do not use the link_to helper to destroy/delete records! Requests that change the state of a program should be done using POST, not GET. If the user accidently reloads a page, it shouldn't change anything in the application. Firefox gives you a warning if you try to reload the page when data has been sent via POST.</p>
<p>You can remove records using the Model.destroy method. A safe alternative to link_to is button_to. Read the following links:</p>
<ul>
<li><a href="http://blog.moertel.com/articles/2005/05/08/taking-the-unsafe-gets-out-of-rails">Taking the unsafe GETs out of Rails</a></li>
<li><a href="http://worsethanfailure.com/Articles/The_Spider_of_Doom.aspx">The Spider of Doom</a></li>
</ul>
<h2>Exercises for the 1337 h4x0r</h2>
<ol>
<li>Give your users the ability to add and remove genres.</li>
<li>Break your application by passing it garbage (for example, http://domain.cxm/artists/view/wheeeeeee) and then fix it so it gracefully handles this input by implementing error handling.</li>
<li>Use form_for to add the ability to edit song details.</li>
<li>Use a layout to make 'Browse by artists' and 'Browse by genres' links universal throughout the app.</li>
<li>Create a website, use Gimp to design an award-winning logo, and then market this and use some of the earnings to order me an Ethanol IV drip.</li>
</ol>
<p><i>Thanks to <a href="http://flickr.com/photos/jcanady/384832937/">jcanady</a> for the photo.</i></p>
<div class="externallinks" style="font-size:80%;">
<strong>External links</strong></p>
<ul>
<li><a href="http://www.railsforum.com/viewtopic.php?id=265">Beginning Relationships</a></li>
<li><a href="http://www.railsenvy.com/2007/8/8/activerecord-tutorial">ActiveRecord Tutorial (rails envy)</a></li>
<li><a href="http://wiki.rubyonrails.org/rails/pages/ActiveRecord">ActiveRecord (RoR wiki)</a></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2007/12/understanding-basic-database-relationships-in-rails/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Using Vim as a Complete Ruby on Rails IDE</title>
		<link>http://biodegradablegeek.com/2007/12/using-vim-as-a-complete-ruby-on-rails-ide/</link>
		<comments>http://biodegradablegeek.com/2007/12/using-vim-as-a-complete-ruby-on-rails-ide/#comments</comments>
		<pubDate>Thu, 13 Dec 2007 23:11:46 +0000</pubDate>
		<dc:creator>Isam</dc:creator>
				<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Tools]]></category>
		<category><![CDATA[editors]]></category>
		<category><![CDATA[gvim]]></category>
		<category><![CDATA[ide]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[vim]]></category>

		<guid isPermaLink="false">http://biodegradablegeek.com/2007/12/13/using-vim-as-a-complete-ruby-on-rails-ide/</guid>
		<description><![CDATA[NOTE: If you are experiencing segmentation faults with vim and rails.vim, see this post. When coding in Ruby on Rails, you&#8217;ll usually be switching between files and running scripts a lot. It can be time-consuming and frustrating coding Rails using a traditional text editor designed for working on big files individually. Vim lets you hop [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/wp-content/uploads/2007/12/vi_traced_with_optical_mouse.jpg" alt="vi traced with optical mouse Using Vim as a Complete Ruby on Rails IDE" align="left" title="Using Vim as a Complete Ruby on Rails IDE" /></p>
<p><br/><br />
<strong>NOTE:</strong> If you are experiencing segmentation faults with vim and rails.vim, <a href="http://biodegradablegeek.com/2008/08/has-vimrailsvim-been-crashing-lately-heres-why/">see this post</a>.</p>
<p>When coding in Ruby on Rails, you&#8217;ll usually be switching between files and running scripts a lot. It can be time-consuming and frustrating coding Rails using a traditional text editor designed for working on big files individually. Vim lets you hop around within a file with enough speed to activate the cosmic treadmill &#8211; but without a plethora of hacks and custom key mappings, it&#8217;s weak as a Rails IDE. Fortunately, for those of us who are reluctant to kick the vim habit, <a href="http://tpope.net">Tim Pope</a> comes to the rescue with rails.vim; A plugin that makes working with Rails in vim painless and efficient. In this guide, I will explain how to install and use rails.vim, along with a few other plugins you&#8217;ll find useful when writing Rails applications.<br />
<span id="more-42"></span></p>
<p>Vim would certainly fail the <i>mom test</i>, and it&#8217;s not something you can learn in one sitting. Learning vim is a lifelong process, and there are many sites and books that go over it extensively, therefore I won&#8217;t do that here. This guide assumes that you at least know what vim is and can open, edit and save files. Rails.vim works for vim, gvim and <a href="http://cream.sourceforge.net/">Cream</a>, so <i>vim</i> in this article is referring to any of these three, unless otherwise stated.</p>
<p>For those who prefer Emacs, check out <a href="http://steve.yegge.googlepages.com/effective-emacs">Effective Emacs by Steve Yegge</a> and the official Wiki&#8217;s <a href="http://wiki.rubyonrails.org/rails/pages/HowToUseEmacsWithRails">HowTouseEmacsWithRails</a>.</p>
<pre>
<strong>TOC</strong>
<a href="#config">Configuring vim/gvim</a>
<a href="#install">Rails.vim and Other Helpful Plugins</a>
<a href="#usage">Usage and Examples</a>
    <a href="#newp">Starting a New Project and Setting Up The Database</a>
        <a href="#dbsetup">Database.yml Setup</a>
    <a href="#models">Generating Models</a>
    <a href="#migrations">Migrations and :Rake</a>
        <a href="#pattern">:Rmigration <i>pattern</i></a>
        <a href="#related">Related Files and The Command :R and its Mapping ]f</a>
    <a href="#dbext">A Glimpse of the Vim Database Extension Plugin</a>
    <a href="#navigation">Controllers, Views and Interfile Navigation</a>
        <a href="#r">:R or ]f</a>
        <a href="#rview">:Rview <i>[[controller/]view]</i></a>
        <a href="#rfind">:Rfind <i>[name]</i></a>
        <a href="#gf">gf ("goto file")</a>
    <a href="#views">Views and Partials</a>
    <a href="#surround">We've Got You Surrounded</a>
        <a href="#caveats">Caveats</a>
        <a href="#add">Adding Surroundings</a>
        <a href="#rep">Replacing Surroundings</a>
        <a href="#rm">Removing Surroundings</a>
        <a href="#custom">Rails.vim and Custom Surroundings</a>
<a href="#neverends">But Wait, There's More</a>
</pre>
<h2 id="config">Configuring Vim/gvim</h2>
<p>Open your vim configuration file or create one if it doesn&#8217;t exist (i.e., new installation):</p>
<ul>
<li>$HOME/.vimrc in Linux and Mac OS X (might be ~/.gvimrc instead)</li>
<li>$HOME\_vimrc (or $HOME\_gvimrc) in Windows</li>
</ul>
<p>If you&#8217;re having trouble finding out where the config file goes, type &#8220;:version&#8221; and hit enter in vim for a list of compile flags, options and directories vim is using.</p>
<p>Add the following to the file and save it (if you must worry about what they do, see <a href="http://vimdoc.sourceforge.net/htmldoc/">the vimdoc</a>)</p>
<pre lang="text" line="1">
filetype on  " Automatically detect file types.
set nocompatible  " We don't want vi compatibility.

" Add recently accessed projects menu (project plugin)
set viminfo^=!

" Minibuffer Explorer Settings
let g:miniBufExplMapWindowNavVim = 1
let g:miniBufExplMapWindowNavArrows = 1
let g:miniBufExplMapCTabSwitchBufs = 1
let g:miniBufExplModSelTarget = 1

" alt+n or alt+p to navigate between entries in QuickFix
map <silent> <m-p> :cp <cr>
map <silent> <m-n> :cn <cr>

" Change which file opens after executing :Rails command
let g:rails_default_file='config/database.yml'

syntax enable
</pre>
<p>Before installing rails.vim, you may want to glance over some additional (g)vim options I use. Otherwise, skip this optional step and <a href="#install">jump directly</a> to the installation.</p>
<p>The following settings in my config are worth looking over. These can be appended to the same vimrc file as above:</p>
<pre lang="text" line="1">
set cf  " Enable error files &#038; error jumping.
set clipboard+=unnamed  " Yanks go on clipboard instead.
set history=256  " Number of things to remember in history.
set autowrite  " Writes on make/shell commands
set ruler  " Ruler on
set nu  " Line numbers on
set nowrap  " Line wrapping off
set timeoutlen=250  " Time to wait after ESC (default causes an annoying delay)
" colorscheme vividchalk  " Uncomment this to set a default theme

" Formatting (some of these are for coding in C and C++)
set ts=2  " Tabs are 2 spaces
set bs=2  " Backspace over everything in insert mode
set shiftwidth=2  " Tabs under smart indent
set nocp incsearch
set cinoptions=:0,p0,t0
set cinwords=if,else,while,do,for,switch,case
set formatoptions=tcqr
set cindent
set autoindent
set smarttab
set expandtab

" Visual
set showmatch  " Show matching brackets.
set mat=5  " Bracket blinking.
set list
" Show $ at end of line and trailing space as ~
set lcs=tab:\ \ ,eol:$,trail:~,extends:>,precedes:<
set novisualbell  " No blinking .
set noerrorbells  " No noise.
set laststatus=2  " Always show status line.

" gvim specific
set mousehide  " Hide mouse after chars typed
set mouse=a  " Mouse in all modes
</pre>
<p>The following optional commands are helpful but require explicit creation of directories and files:</p>
<pre lang="text" line="1">
" Backups &#038; Files
set backup                     " Enable creation of backup file.
set backupdir=~/.vim/backups " Where backups will go.
set directory=~/.vim/tmp     " Where temporary files will go.
</pre>
<p>Run vim to make sure it doesn't halt to display any warnings or error messages. If it does, check that the specific folders (~/.vim/skeletons and ~/.vim/backups etc) exist and vim has write permission on them.</p>
<h2 id="install">Rails.vim and Other Helpful Plugins</h2>
<p>Installing vim plugins just requires putting files where they belong in vim's root directory. We will be installing rails.vim along with some dependency plugins and a few others that make coding Rails in vim much simpler.</p>
<p>Below is a list of all the plugins you need to download and install. If they are <strong>.vim files</strong>, move them into your <i>plugin</i> folder, probably $HOME/.vim/plugin or $VIM\vimfiles\plugin (probably C:\vim\vimfiles\plugin). <strong>Doc files (.txt)</strong> go in $HOME/.vim/doc or vimfiles\doc\. Do the same with the contents of compressed files after you've extracted them. Again, if you're having trouble locating where these files should go, type ":version" in vim and hit enter.</p>
<ul>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1567">rails.vim</a>: This is the magic. The rails.zip file contains plugin/rails.vim and doc/rails.txt. Both should be moved into their proper location in your root vim directory ($VIM).</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=69">Project</a>: This adds a list of frequently used files to the lefthand side of vim. Rails.vim utilizes this script to create a directory tree of your Rails application. You're probably familiar with this feature already, as is a basic feature of most modern IDEs.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=197">genutils 1.20 <strong>(NOT 2.x)</strong></a>: Adds many useful functions</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=171">multvals.vim</a>: genutils depends on this.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=159">minibufexpl.vim</a>: This adds (ugly, but functional) tabs to vim, making it much easier to keep track of the many files you'll be working on simultaneously.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=356">dbext.vim</a>: Adds database support to vim. This integrates seemlessly with rails.vim. More on it below.</li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1697">surround</a>: Surround.vim adds mappings to let you easily work with "surroundings" in pairs. Such as { }, " " and < >. More on it below.</li>
</ul>
<p>To get the help files working, Rails needs to generate help tags from the txt files you placed in the doc directory. Open vim and in <i>normal</i> (command) mode type the following and hit enter:<br />
<strong>Linux:</strong> :helptags $HOME/.vim/doc<br />
<strong>Windows:</strong> :helptags $VIM\vimfiles\doc</p>
<p>Your directory might differ from the above. In which case, again, check ":version<enter>"</p>
<p>Make sure it worked:</p>
<pre lang="text" line="1">
:help rails
</pre>
<p>For more information on vim's help feature, use <strong>:help help</strong> or read about it <a href="http://www.vim.org/htmldoc/various.html#:help">in your browser</a>. For help about a specific command, use :help <i>command</i>. Command can be a vim, rails.vim or other plugin command. For example <i>:help rails</i> or <i>:help rgenerate</i>.</p>
<h2 id="usage">Usage and Examples</h2>
<p>Usage might seem intimidating at first because the plugins have-on top of vim's already rich set of functions-added so much more functionality and commands to memorize, but you'll quickly realize that getting used to rails.vim is easy due to the natural command names (and tab completion). Let's begin by creating a dummy rails project.</p>
<h3 id="newp">Starting a New Project and Setting Up The Database</h3>
<p>In Cream or gvim, you can create projects using the menu </strong>Plugin -> Rails -> Projects -> New</strong>. Alternatively, you can use the <strong>:Rails</strong> command in <i>normal</i> mode. Both the menu option and the :Rails command are wrappers for the native <i>rails</i> application, making it possible to pass them what you would normally pass <i>rails</i> in the console.</p>
<p><i>If you do not specify an absolute path when passing :Rails your project name, the rails application will be generated in the current working directory, usually the directory you were in when you started vim.</i></p>
<p>Let's create a new framework named <i>dummy</i>. This command is typed in vim while in command mode (not the mode you type content in) and followed with the Enter key. Change /tmp/ to where ever you want this to reside (I.e., C:\Windows\Temp\):</p>
<pre lang="text" line="1">
:Rails /tmp/dummy
</pre>
<p><strong id="dbsetup">Database.yml Setup</strong><br />
The usual rails output will scroll across the screen and you will be dumped at the default file you specified in the vimrc file (g:rails_default_file). This will be README by default. If you haven't changed it to database.yml like in my config above, you can jump to the database config file by typing <strong>:Rfind database.yml</strong>.</p>
<p>Put your database information under <i>dummy_development</i> and save as usual (:w). Now creating our dummy_development database is as easy as one short command:</p>
<pre lang="text" line="1">
:Rdbext!
</pre>
<p><i>(You can use a database frontend (like the excellent <a href="http://www.phpmyadmin.net">PHPMyAdmin</a>) or the mysql command in a console to create your dummy_development database if you did not install dbext.)</i></p>
<p><strong>Note:</strong> This issues a CREATE DATABASE command on the Rails environment in $RAILS_ENV, which is <i>development</i> by default, but you can have it create the <i>test</i> and <i>production</i> environments as well:</p>
<pre lang="text" line="1">
:Rdbext! test
:Rdbext! production
</pre>
<p>The last loaded environment configuration is what will be used throughout the Rails application. To change the environment, just provide the desired one as a parameter to the :Rdbext command (notice lack of bang: <strong>!</strong>). If you've created three environments and want to switch to the test environment:</p>
<pre lang="text" line="1">
:Rdbext test
</pre>
<p>This commands opens up a Results tab and displays the results on the bottom of the screen in a new window. Sometimes, this window can be intrusive and downright annoying. To close it, click it and hit <strong>ctrl+w</strong>, let go of both and quickly hit <strong>c</strong>.</p>
<p>For more information, check <strong>:help Rdbext</strong>. More on DBExt later.</p>
<h3 id="models">Generating Models</h3>
<p>If you wish to run something in the application's script directory, you can use :Rscript:</p>
<pre lang="text" line="1">
:Rscript about
:Rscript console
:Rscript breakpointer
etc...
</pre>
<p>but you will probably never need to, as Rails.vim provides wrappers for most of Rails' scripts and functions. The names of these will usually be <strong>:R</strong> followed by the name of the script. For example, :Rgenerate, :Rserver, :Rconsole, etcetra...</p>
<p>:Rgenerate takes the same parameters as Rails' generate script. Let's generate a model named Thing:</p>
<pre lang="text" line="1">
:Rgenerate model Thing
</pre>
<p>The model file is automatically loaded and given focus after its creation. Notice that you can still access database.yml via its tab on top of the vim window. Double click a tab to open it, and click it once to give it focus, then hit <strong>d</strong> to close it. Try that now on database.yml (and Results if it's still open). More on tabs and the minibufexpl later.</p>
<h3 id="migrations">Migrations and :Rake</h3>
<p>Let's edit the model's migration file, which is created automatically for each generated model. You have a number of choices for jumping to this file:</p>
<p><strong id="pattern">:Rmigration <i>pattern</i></strong><br />
The optional <i>pattern</i> can be any part of the migration's filename (in this case, 001_create_things.rb). You can use <i>things</i> (notice it's plural) because it matches the filename:</p>
<pre lang="text" line="1">
:Rmigration things
</pre>
<p>The migration number with or without the zeros. All three examples open the same migration:</p>
<pre lang="text" line="1">
:Rmigration 1
:Rmigration 01
:Rmigration 001
</pre>
<p>or any string of characters that match part of that migration's filename without causing an ambiguity, like 001_crea<strong>te_t</strong>hings.rb:</p>
<pre lang="text" line="1">
:Rmigration te_t
</pre>
<p>Rmigration is context aware. It will default to opening the <i>related</i> migration file if executed without a parameter while the model file is open:</p>
<pre lang="text" line="1">
:Rmigration
</pre>
<p>More on related files below.</p>
<p><strong>Related files and the command :R and its mapping ]f</strong><br />
The <strong>:R</strong> command or its mapping <strong>]f</strong> open up the related file of whatever is currently open. A related file is something that is usually associated with the file you are opening. This is a construct in rails.vim, and that's where the rules are defined. For example, a model's related file is its migration. Even though both can be independent (you can have migrations without models and vice versa). Don't think about this too much.</p>
<p>Below is an excerpt from <strong>:help rails-related</strong>. It shows a list of what file will be open when :R is issued while the Current File is open:</p>
<pre lang="text" line="1">
<strong>Current File            Related File</strong>
model            related migration
controller (in method)    template (view)
template (view)            controller (jump to method)
migration            next migration
config/routes.rb        config/environment.rb
</pre>
<p>Open the migration file and add the following to the create_table block in the self.up method:</p>
<pre lang="Rails" line="1">
t.column :description, :text
t.column :weight, :integer
</pre>
<p>After writing your self.up, you can use :Rinvert to have self.down automatically generated. You don't have to do this here because self.down is already filled in (drop_table), but let's try it anyway by creating a test table called "test" and using :Rinvert to update self.down. Your self.up should now look like this:</p>
<pre lang="Rails" line="1">
  def self.up
    create_table :things do |t|
      t.column :description, :text
      t.column :weight, :integer
    end
    create_table :test do |t|
      t.column :hi
    end
  end
</pre>
<p>and after running :Rinvert, your self.down will be:</p>
<pre lang="Rails" line="1">
  def self.down
    drop_table :test
    drop_table :things
  end
</pre>
<p>:Rinvert works great for most commands, even some complex queries, but it can't reverse everything. A low level SQL query or a blank self.up might produce an IrreversableMigration error. Let's apply our migration to the database by running <strong>:Rake</strong>. It defaults to db:migrate when run in the context of our migration file.</p>
<pre lang="text" line="1">
:Rake
</pre>
<h3 id="dbext">A Glimpse of the Vim Database Extension Plugin</h3>
<p>DBExt is powerful and deserves its own paper, but before getting derailed from our main topic, here are some useful DBExt commands:</p>
<p><strong>:DBDescribeTable <i>table</i></strong> outputs a table's columns and their data types. Run it now on the <i>things</i> table:</p>
<pre lang="text" line="1">
:DBDescribeTable things

Connection: T(MYSQL)  D(bic_development)  U(username)
Field    Type    Null    Key        Default        Extra
id    int(11)    NO        PRI        NULL        auto_increment
description    text    YES        NULL
weight    int(11)    YES        NULL
</pre>
<p><strong>:DBExecSQL <i>query</i></strong> executes low level SQL queries that are either under the cursor, or passed as parameters. Let's use it to populate our table:</p>
<pre lang="text" line="1">
:DBExecSQL INSERT INTO things VALUES (1, 'Worlds fattest man', 1200);
:DBExecSQL INSERT INTO things VALUES (2, 'Four quarter pounders', 1);
</pre>
<p>Let's view the contents of the <i>things</i> table:</p>
<pre lang="text" line="1">
:DBSelectFromTable things
</pre>
<p><i>If the results window on the bottom gets stuck, click it and then hit ctrl+w the c to close it.</i></p>
<p>Read the extensive help file using <strong>:help DBExt</strong>.</p>
<h3 id="navigation">Controllers, Views and Interfile Navigation</h3>
<p>Let's create a controller and a skeleton for a method named index:</p>
<pre lang="text" line="1">
:Rgenerate controller Things index
</pre>
<p>We want to display all the records from our Thing table in our index view. Let's add some code this controller's index method:</p>
<pre lang="Rails" line="1">
def index
    @people = Thing.find(:all)
end
</pre>
<p>For test purposes later, add the following method to ThingsController, under the index method:</p>
<pre lang="Rails" line="1">
def viewless
    @cast = "Cloud Strife"
end
</pre>
<p>Since we passed a method name (<i>index</i>) to :Rgenerate, Rails has automatically generated a view for that method. We have a number of ways to navigate to that view:</p>
<p><strong id="r">:R or ]f</strong><br />
The Related command was discussed above under <a href="#migrake">Migrations and :Rake</a>. A controller can have many views, so :R looks at the current method the cursor resides in to look up what view to open. Place the cursor anywhere in the index method and type :R (or hit <i>]f</i>) to open up index.rhtml.</p>
<p>This command only works if the related file exists. If the view doesn't exist, you'll get an "E345: Can't find file ... in path" error. Try this by putting the cursor on the viewless method before running the :R command again.</p>
<p>You can use :RS to split (what the S stands for) the current window into two, allowing you to view and edit both the controller and view simultaneously.</p>
<p><strong id="rview">:Rview <i>[[controller/]view]</i></strong><br />
Typed with no arguments, this command behaves the same as :R. If that view doesn't exist, you can specify a name, either by the full path or just the view name and extension, and that view will be created.</p>
<p>For example, let's create a view on the fly for the viewless method (extension is mandatory):</p>
<pre lang="text" line="1">
:Rview viewless.rhtml
</pre>
<p>We haven't defined a controller above, so by default, :Rview assumes it is for the current controller. It will go into app/views/things/. We could specify a controller by using <strong>:Rview controller/view_name.extension</strong>.</p>
<p>Note that the file is only generated in memory and must be saved to disk explicitly (:w).</p>
<p><strong>Alternating between files</strong></p>
<p>A lot of times, you'll be working exclusively on two files, back and forth. To alternate between the current file and the last file you were editing, use <i>CTRL+^</i> (although in practice, you're actually just hitting CTRL+6).</p>
<p>Rails.vim also has an <i>alternate</i> command (:A or the [f mapping), similar in function to related. It usually takes you to the current file's test file.</p>
<p>From <strong>:help rails-alternate</strong>, this tells you what the alternate file will be for the Current File open:</p>
<pre lang="text" line="1">
<strong>Current file      Alternate file</strong>
model                               unit test
controller (in method)    functional test
template (view)              helper
migration                         previous migration
config/routes.rb               config/database.yml
</pre>
<p><strong id="rfind">:Rfind <i>[name]</i></strong><br />
Like vim's :find command, this one also opens a file it finds either by the name you pass it or by whatever is under the cursor (behaves similarly to <i>gf</i>, more on that below). Rails.vim enhances the native command by giving it the ability to find files by controller and model name.</p>
<p>This opens the Thing model:</p>
<pre lang="text" line="1">
:Rfind thing
</pre>
<p>This opens the Things controller (case sensitive):</p>
<pre lang="text" line="1">
:Rfind ThingsController
</pre>
<p>This opens the index.rhtml view (you must be in the ThingsController):</p>
<pre lang="text" line="1">
:Rfind index
</pre>
<p><strong id="gf">gf ("goto file")</strong><br />
In rails.vim, the <i>gf</i> mapping is used to jump to a file under the cursor taking context into account. The following is from <strong>:help rails-gf</strong>:<br />
---<br />
Example uses of gf, and where they might lead. <i>(* indicates cursor position)</i><br />
    Pos*t.find(:first)<br />
    app/models/post.rb</p>
<p>    has_many :c*omments<br />
    app/models/comment.rb</p>
<p>    link_to "Home", :controller => :bl*og<br />
    app/controllers/blog_controller.rb</p>
<p>    <%= render :partial => 'sh*ared/sidebar' %><br />
    app/views/shared/_sidebar.rhtml</p>
<p>    <%= stylesheet_link_tag :scaf*fold %><br />
    public/stylesheets/scaffold.css</p>
<p>    class BlogController < Applica*tionController<br />
    app/controllers/application.rb</p>
<p>    class ApplicationController < ActionCont*roller::Base<br />
    .../action_controller/base.rb</p>
<p>    fixtures :pos*ts<br />
    test/fixtures/posts.yml</p>
<p>    layout :pri*nt<br />
    app/views/layouts/print.rhtml</p>
<p>    # In the Blog controller<br />
    def li*st<br />
    app/views/blog/list.rhtml</p>
<p>    <%= link_to "New", new_comme*nt_path %><br />
    app/controllers/comments_controller.rb (jumps to def new)</p>
<p>In the last example, the controller and action for the named route are determined by evaluating routes.rb as Ruby and doing some introspection. This means code from the application is executed. Keep this in mind when navigating unfamiliar applications.<br />
---</p>
<p>Add the following to the index.rhtml view file, overwriting the default code already in there:</p>
<pre lang="html" line="1">
<h1>All the things in our Thing table</h1>

&lt;h1&gt;All the things in our Thing table&lt;/h1&gt;
<ol>
  <% @stuff.each do |x| %>
<li>
    <%= x.description %> (weight: <%= x.weight %> pound(s))
    </li>

  <% end %>
</ol>
</pre>
<h3 id="views">Views and Partials</h3>
<p>The :Rextract command (:Rpartial is deprecated) makes creating <a href="http://wiki.rubyonrails.org/rails/pages/Partials">partials</a> a breeze. You choose a range of lines and supply the command a name you want for the new partial. The lines get replaced by a call to render the newly created partial, which now holds the lines that were extracted.</p>
<p>Let's try using this by delegating output code between the &lt;li&gt; and &lt;/li&gt; tags in our index.rhtml view into a partial named "ppp" by explicitly defining the line numbers (your line numbers might not match. Alter it accordingly):</p>
<pre lang="text" line="1">
:5,5Rextract ppp
</pre>
<p>A new partial with the filename _ppp.rhtml is created containing line #5 from our index.rhtml view. Line #5 now is a call to render the newly created ppp view: <i><%= render :partial => 'ppp' %></i> - The new partial only exists in memory at this point, and must be saved to disk explicitly.</p>
<p>This could also have been done in visual mode, selecting the lines we want extracted visually instead of by line numbers. Place the cursor at the beginning of the line, press v to enter visual mode and hit '$' (shift+4) to jump to the end of the line, selecting the entire line along the way. Now hit : and type :Rextract ppp (it will come out as <i>:'<,'>Rextract ppp</i>) and hit enter. Same effect as above.</p>
<h3 id="surround">We've Got You Surrounded</h3>
<p>Whether you're coding, writing, or editing, Tim Pope's surround plugin is very useful. It adds vim mappings to add, remove or edit "surroundings." A surrounding is a pair of parentheses, brackets, quotes, tags, etc.</p>
<p>Some mappings require that you press the first few keystrokes within a second. For full functionality, make sure you're using vim 7 or greater. Let's begin by making sure the plugin is installed and works properly by testing a command:</p>
<p>Type <i>(hello world)</i> into vim, and with your cursor anywhere in that phrase, hit <strong>ds(</strong>. If <i>(hello world)</i> turns to <i>hello world</i>, the plugin is working fine. If not, then make sure you're installed it correctly and are using Vim 7.0.</p>
<p><strong id="caveats">Caveats</strong><br />
* The keystrokes need to be typed in succession very fast. The <i>timeoutlen</i> setting in the vim config file can impair the ys* functions. The smaller the value for <i>timeoutlen</i>, the less time you have in between keystrokes to ensure vim catches the command. I set <i>timeoutlen</i> to 200, but put 250 as the value in the example vimrc at the beginning of this tutorial. Delete this setting or use a higher value (300+) if you're having trouble using commands like yssa or yss.</p>
<p>* b, B, r, and a are aliases for ), }, ], and > respectively, and t represents a pair of HTML or XML tags.</p>
<p>* In the examples below, the cursor position is represented by an asterisk (*).</p>
<p><strong id="add">Adding Surroundings</strong><br />
You can add a pair of surroundings around a word, line, sentence, paragraph or a specific number of characters.</p>
<p>Adding quotes around a word:<br />
<u>Old text | Command | Result</u><br />
H*eya world | ysiw" | "Heya" world</p>
<p>Adding a pair of tags around a word:<br />
<u>Old text | Command | Result</u><br />
I*talic text | ysiw&lt;i&gt; | &lt;i&gt;Italic&lt;/i&gt; text</p>
<p>Adding arrows around a sentence:<br />
<u>Old text | Command | Result</u><br />
Clandestin*e operation | yssa | &lt;Clandestine operation&gt;</p>
<p>An angry Kenny face:<br />
<u>Old text | Command | Result</u><br />
*>< | yss)yss)yss( | ( ((><)) )<br />
<i>(notice usage of parantheses in the command. Using the opening bracket adds spaces between the target being surrounded.)</i></p>
<p><strong id="rep">Replacing Surroundings</strong><br />
Replacing parentheses with quotes in a word:<br />
<u>Old text | Command | Result</u><br />
(qu*ack) quack | cs(" | "quack" quack</p>
<p>Changing those double quotes to a pair of tags:<br />
<u>Old text | Command | Result</u><br />
"q*uack" quack | cs"<qqqqq> | <qqqqq>quack</qqqqq> quack</p>
<p>Changing those tags to brackets:<br />
<u>Old text | Command | Result</u><br />
&lt;qqqqq&gt;q*uack&lt;/qqqqq&gt; quack | cstr | [quack] quack</p>
<p><strong id="rm">Removing Surroundings</strong><br />
Remove quotes around a word:<br />
<u>Old text | Command | Result</u><br />
Hash "eater*"  | ds" | Hash eater</p>
<p>Remove tags around a word:<br />
<u>Old text | Command | Result</u><br />
&lt;h1&gt;h*ead&lt;/h1&gt; | dst | head</p>
<p>Removing multiple surroundings around a sentence:<br />
<u>Old text | Command | Result</u><br />
{"(iiight)"} | ds(ds"dsB | iiight</p>
<p><strong id="custom">Rails.vim and Custom Surroundings</strong><br />
Rails.vim makes use of the surround plugin by adding a few useful surroundings. These only work when rails.vim is enabled (when RoR projects are open):</p>
<p><u>Old text | Command | Result</u><br />
*end | yss= | <%= end %></p>
<p><u>Old text | Command | Result</u><br />
*end | yss- | <%= end -%></p>
<p><u>Old text | Command | Result</u><br />
*cat | yss# | <%# cat %></p>
<p>You can create custom surroundings. Here's one example:<br />
:let g:surround_65 = "&lt;a href=\"\"&gt; \r &lt;/a&gt;"</p>
<p>65 is the ASCII decimal for the 'A' character. You can use <a href="http://web.cs.mun.ca/~michael/c/ascii-table.html">an ascii table</a> to find the decimal corresponding to the character you want to use.</p>
<p>Usage:<br />
<u>Old text | Command | Result</u><br />
I*Shot The Sheriff | yssA | &lt;a href=""&gt; I Shot The Sheriff &lt;/a&gt;</p>
<p>Be sure to read the extensive help files :help surround and :help rails-surround. They provide details and examples.</p>
<h2 id="neverends">But Wait, There's More</h2>
<p>We've merely scratched the surface of rails.vim here. Be sure to check out the <a href="http://rails.vim.tpope.net/">Official rails.vim Website</a>, the <a href="http://tpope.net">author's site</a>, and the external links I provided below. For those looking for a more user-friendly, "real" GUI-based (as opposed to a TUI) IDE based around vim, try out <a href="http://vimmate.rubyforge.org/">VimMate</a>.</p>
<div class="externallinks" style="font-size:80%;">
<strong>External links</strong></p>
<ul>
<li><a href="http://wiki.rubyonrails.org/rails/pages/HowtoUseVimWithRails">How To Use Vim With Rails (official RoR wiki)</a></li>
<li><a href="http://ruby.about.com/od/railsvim/railsvim_Ruby_on_Rails_IDE.htm">Rails.vim RoR IDE (About.com)</a></li>
<li><a href="http://www.vim.org/scripts/script.php?script_id=1658">NERD tree - A great plugin that adds a nested file explorer to vim, much like the Project plugin</a></li>
<li><a href="http://eigenclass.org/hiki.rb?rcodetools">rcodetools</a></li>
</ul>
<p><i>Thanks to <a href="http://flickr.com/photos/heyvikram/152929481/">_vikram</a> for the vi photo. It was done using an optical mouse and a long exposure. He was actually attempting to spell out "vik"</i>
</div>
]]></content:encoded>
			<wfw:commentRss>http://biodegradablegeek.com/2007/12/using-vim-as-a-complete-ruby-on-rails-ide/feed/</wfw:commentRss>
		<slash:comments>33</slash:comments>
		</item>
	</channel>
</rss>

