<?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>Moki Systems Blog &#187; Ruby on Rails</title>
	<atom:link href="http://www.mokisystems.com/blog/category/ruby-on-rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mokisystems.com/blog</link>
	<description>Addressing such topics as: web programming, design, ruby on rails, cake php, postgresql, linux, seo</description>
	<lastBuildDate>Thu, 19 Aug 2010 00:18:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Savings records that fail validation.</title>
		<link>http://www.mokisystems.com/blog/savings-records-that-fail-validation/</link>
		<comments>http://www.mokisystems.com/blog/savings-records-that-fail-validation/#comments</comments>
		<pubDate>Tue, 09 Jun 2009 19:39:15 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=62</guid>
		<description><![CDATA[So I had this problem with a record that was being saved even though it failed validation:

cc = CreditCard.new&#40;:card_number =&#62; 'invalid'&#41;
&#62;&#62; cc.save
=&#62; false
&#62;&#62; cc.id
=&#62; 3

That one had me stumped for a while until I realized I was carelessly using update_attribute in my custom writer:

def card_number=&#40;num&#41;
  update_attribute&#40;:crypted_card_number, encrypt&#40;num&#41;&#41;
end

And we all know that update_attribute &#8220;saves the [...]]]></description>
			<content:encoded><![CDATA[<p>So I had this problem with a record that was being saved even though it failed validation:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">cc = CreditCard.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:card_number</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'invalid'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> cc.<span style="color:#9900CC;">save</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">false</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> cc.<span style="color:#9900CC;">id</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">3</span></pre></div></div>

<p>That one had me stumped for a while until I realized I was carelessly using update_attribute in my custom writer:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#9966CC; font-weight:bold;">def</span> card_number=<span style="color:#006600; font-weight:bold;">&#40;</span>num<span style="color:#006600; font-weight:bold;">&#41;</span>
  update_attribute<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:crypted_card_number</span>, encrypt<span style="color:#006600; font-weight:bold;">&#40;</span>num<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And we all know that <a href="http://apidock.com/rails/ActiveRecord/Base/update_attribute">update_attribute</a> &#8220;saves the record without going through the normal validation procedure.&#8221;</p>
<p>Everything worked much nicer after I changed the code to:</p>
<pre code="ruby">
def card_number=(num)
  self.crypted_card_number = encrypt(num)
end
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/savings-records-that-fail-validation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby thinks (19.99 * 100).to_i = 1998</title>
		<link>http://www.mokisystems.com/blog/ruby-thinks-1999-100to_i-1998/</link>
		<comments>http://www.mokisystems.com/blog/ruby-thinks-1999-100to_i-1998/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 15:25:42 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=60</guid>
		<description><![CDATA[
&#62;&#62; &#40;19.99 * 100&#41;.to_i
=&#62; 1998
&#62;&#62; &#40;9.99 * 100&#41;.to_i
=&#62; 999

Someone please tell me what&#8217;s up with that!
In the meantime:

&#62;&#62; &#40;19.99 * 100&#41;.to_s.to_i
=&#62; 1999

]]></description>
			<content:encoded><![CDATA[
<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">19.99</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_i</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1998</span>
<span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">9.99</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_i</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">999</span></pre></div></div>

<p>Someone please tell me what&#8217;s up with that!</p>
<p>In the meantime:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#006600; font-weight:bold;">&gt;&gt;</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">19.99</span> <span style="color:#006600; font-weight:bold;">*</span> <span style="color:#006666;">100</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">to_i</span>
<span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">1999</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/ruby-thinks-1999-100to_i-1998/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A Couple Rails Find Gotchas</title>
		<link>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/</link>
		<comments>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/#comments</comments>
		<pubDate>Tue, 03 Mar 2009 16:07:22 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=59</guid>
		<description><![CDATA[We ran into a few little gotchas with ActiveRecord&#8217;s find method when upgrading from Rails 2.1.1 to 2.2.2. The solutions are pretty trivial, so the main lesson here is to test your code so things like this get caught by your test suite and not the client.

Gotcha #1

>> Rails.version
=> "2.1.1"
>> Client.find_all_by_notify_by(%w(email txt both)).size
=> 2


>> Rails.version
=> [...]]]></description>
			<content:encoded><![CDATA[<p>We ran into a few little gotchas with ActiveRecord&#8217;s find method when upgrading from Rails 2.1.1 to 2.2.2. The solutions are pretty trivial, so the main lesson here is to test your code so things like this get caught by your test suite and not the client.</p>
<p><span id="more-59"></span></p>
<h3>Gotcha #1</h3>
<p><code><br />
>> Rails.version<br />
=> "2.1.1"<br />
>> Client.find_all_by_notify_by(%w(email txt both)).size<br />
=> 2<br />
</code></p>
<p><code><br />
>> Rails.version<br />
=> "2.2.2"<br />
>> Client.find_all_by_notify_by(%w(email txt both)).size<br />
ActiveRecord::StatementInvalid: Mysql::Error: Operand should contain 1 column(s): SELECT * FROM `clients` WHERE (notify_by = 'email','txt','both' AND clients.deleted_at IS NULL)<br />
>> Client.find(:all, :conditions => ["notify_by = ? OR notify_by = ? OR notify_by = ?", *%w(email txt both)]).size<br />
=> 2<br />
</code></p>
<h3>Gotcha #2</h3>
<p><code><br />
>> Rails.version<br />
=> "2.1.1"<br />
>> Client.find_all_by_agent_id(nil).size<br />
=> 26<br />
</code></p>
<p><code><br />
>> Rails.version<br />
=> "2.2.2"<br />
>> Client.find_all_by_agent_id(nil).size<br />
=> 0<br />
>> Client.find(:all, :conditions => "agent_id IS NULL").size<br />
=> 26<br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/a-couple-rails-find-gotchas/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Vim as a Ruby on Rails IDE</title>
		<link>http://www.mokisystems.com/blog/vim-as-a-ruby-on-rails-ide/</link>
		<comments>http://www.mokisystems.com/blog/vim-as-a-ruby-on-rails-ide/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 17:47:11 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=56</guid>
		<description><![CDATA[In the words of Tim Pope &#8220;TextMate may be the latest craze for developing Ruby on Rails applications, but Vim is forever&#8221;
Here&#8217;s how I use vim (and gnome-terminal) to program in Rails on Ubuntu.

I have a ruby script that opens two gnome-terminals each with 9 tabs each. That may seem like a lot, but each [...]]]></description>
			<content:encoded><![CDATA[<p>In the words of <a href="http://www.vim.org/scripts/script.php?script_id=1567">Tim Pope</a> &#8220;TextMate may be the latest craze for developing Ruby on Rails applications, but Vim is forever&#8221;</p>
<p>Here&#8217;s how I use vim (and gnome-terminal) to program in Rails on Ubuntu.</p>
<p><!-- More --></p>
<p>I have a <a href="http://github.com/eremite/binfiles/tree/master/zvim_rails_ide">ruby script</a> that opens two gnome-terminals each with 9 tabs each. That may seem like a lot, but each one is assigned a specific purpose and by now my fingers know just where to go depending on the task at hand. For example, models, views and controllers each get their own tab. So if I need to edit a model my fingers will do an <Alt-1>vim model_name.rb (or :e model_name.rb if I&#8217;m already in vim). And of course <a href="http://github.com/eremite/dotfiles/tree/master/bashrc">bash aliases</a> and tab_completion minimizes the actual number of keystrokes required. In the same way, I know exactly where to go to watch the log, play in the console, use the SCM or anything else.</p>
<p><a href='http://www.mokisystems.com/blog/wp-content/uploads/2008/12/zvim_rails_ide.png'><img src="http://www.mokisystems.com/blog/wp-content/uploads/2008/12/zvim_rails_ide-300x174.png" alt="My Vim Rails IDE" title="vim_rails_ide" width="300" height="174" class="alignnone size-medium wp-image-57" /></a></p>
<p>So that&#8217;s what it actually looks like. Notice how I have Gmail in the background so I can know immediately when I get a new email or IM (and ignore it at my leisure). Not shown is a separate Firefox window running on my other monitor so that I can see both the code and the running application at the same time.</p>
<p>Now, I have some doubts as to how well my solution would work for other people as it requires a bit of discipline to make sure <a href="http://www.google.com/search?hl=en&#038;q=%22A+place+for+everything+and+everything+in+its+place%22&#038;btnG=Search">everything has a place</a> and to train yourself to always do things in the right place. It seems <a href="http://weblog.jamisbuck.org/2008/10/10/coming-home-to-vim">most people</a> prefer to have only a few windows (or tabs or buffers or whatever) open and use some sort of <a href="http://github.com/jamis/fuzzyfinder_textmate/tree/master">fuzzy finder</a> or <a href="http://www.vim.org/scripts/script.php?script_id=1658">file explorer</a> to find the file they want to work on next. But that&#8217;s what I love about vim. I can come up with a custom workflow that works for me instead of conforming to the whims of some dictatorial IDE. True, the learning curve was quite steep at first, and I still occasionally invest some of my time in learning how to use additional features and <a href="http://github.com/eremite/dotfiles/tree/master/vimrc">customizations</a>, but now contemplating using another text editor is like going back to riding tricycles after learning to fly jet planes.</p>
<p>Here&#8217;s the current version of the ruby script in case anyone&#8217;s interested. I call it zvim_rails_ide so I can use it with a quick zv&lt;tab&gt;.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#008000; font-style:italic;">#!/usr/bin/env ruby</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">if</span> ARGV.<span style="color:#9900CC;">size</span>.<span style="color:#9900CC;">zero</span>?
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;Usage: #{File.basename($0)} name_of_project&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">exit</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
RAILS_ROOT = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">pwd</span>, ARGV<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
RAILS_ROOT <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">'/'</span> <span style="color:#9966CC; font-weight:bold;">unless</span> RAILS_ROOT<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span> =~ <span style="color:#006600; font-weight:bold;">%</span>r<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">/</span>$<span style="color:#006600; font-weight:bold;">&#125;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{RAILS_ROOT}: No such file or directory&quot;</span>
  <span style="color:#CC0066; font-weight:bold;">exit</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
ls = <span style="color:#996600;">&quot;ls --color&quot;</span>
scm = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'.git'</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#996600;">'git status'</span> : <span style="color:#996600;">'svn status'</span>
test_dir = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">exists</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{RAILS_ROOT}spec&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#996600;">'spec'</span> : <span style="color:#996600;">'test'</span>
&nbsp;
<span style="color:#006600; font-weight:bold;">&#91;</span>
  <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#ff3333; font-weight:bold;">:geometry</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;140x38+90+270&quot;</span>,
    <span style="color:#ff3333; font-weight:bold;">:tabs</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;app/models&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;app/views&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;app/controllers&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;app/helpers&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;public&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;vendor&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> test_dir, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> test_dir, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>,
  <span style="color:#006600; font-weight:bold;">&#123;</span>
    <span style="color:#ff3333; font-weight:bold;">:geometry</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;141x32+185+110&quot;</span>,
    <span style="color:#ff3333; font-weight:bold;">:tabs</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> scm<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;lib&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;ruby script/console&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;config/locales&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>,
      <span style="color:#006600; font-weight:bold;">&#123;</span>:path <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:command</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> ls<span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#006600; font-weight:bold;">&#93;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span>
<span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>window<span style="color:#006600; font-weight:bold;">|</span>
  tabs = window<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:tabs</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>tab<span style="color:#006600; font-weight:bold;">|</span> <span style="color:#996600;">&quot;--tab-with-profile=DEFAULT --working-directory='#{RAILS_ROOT}#{tab[:path]}' -e <span style="color:#000099;">\&quot;</span>bash -c '#{tab[:command]}; bash'<span style="color:#000099;">\&quot;</span>&quot;</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">' '</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">system</span> <span style="color:#996600;">&quot;gnome-terminal --geometry #{window[:geometry]} #{tabs}&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/vim-as-a-ruby-on-rails-ide/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Rails’ New I18n Support in Real Life: Part the Fourth</title>
		<link>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-fourth/</link>
		<comments>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-fourth/#comments</comments>
		<pubDate>Tue, 16 Dec 2008 15:35:00 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=54</guid>
		<description><![CDATA[So after tediously going through your entire site and extracting all displayed strings to a separate translation file, how do you know you didn&#8217;t miss something somewhere? My solution was to create a quick rake task that machine translates my English yaml file to something else. A quick sudo aptitude install bsdgames and I had [...]]]></description>
			<content:encoded><![CDATA[<p>So after tediously going through your entire site and extracting all displayed strings to a separate translation file, how do you know you didn&#8217;t miss something somewhere? My solution was to create a quick rake task that machine translates my English yaml file to something else. A quick <em>sudo aptitude install bsdgames</em> and I had pig latin at my fingertips. So I switched to that and browsed through the site and looked for anything that hadn&#8217;t changed. And I found quite a bit of stuff that I had missed.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#008000; font-style:italic;"># lib/tasks/pig.rake</span>
desc <span style="color:#996600;">&quot;Creates a config/locales/pig-US.yml from config/locales/en-US.yml&quot;</span>
task <span style="color:#ff3333; font-weight:bold;">:pig</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:environment</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  DEFAULT_LOCALE = <span style="color:#996600;">'en-US'</span>
  <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">'config'</span>, <span style="color:#996600;">'locales'</span>, <span style="color:#996600;">'pig-US.yml'</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#996600;">&quot;w&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>fout<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#CC0066; font-weight:bold;">readlines</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span>RAILS_ROOT, <span style="color:#996600;">'config'</span>, <span style="color:#996600;">'locales'</span>, <span style="color:#996600;">&quot;#{DEFAULT_LOCALE}.yml&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>line<span style="color:#006600; font-weight:bold;">|</span>
      <span style="color:#9966CC; font-weight:bold;">unless</span> line =~ <span style="color:#006600; font-weight:bold;">/</span><span style="color:#996600;">&quot;/
        fout.puts line.sub(DEFAULT_LOCALE, 'pig-US')
      else
        key, *translation = line.split(':')
        translation = translation.join(':')
        translation.split(/(&quot;</span>.<span style="color:#9900CC;">*</span>?<span style="color:#996600;">&quot;)/).each do |quote|
          if quote =~ /&quot;</span><span style="color:#006600; font-weight:bold;">/</span>
            quote.<span style="color:#CC0066; font-weight:bold;">gsub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'&quot;'</span>, <span style="color:#996600;">''</span><span style="color:#006600; font-weight:bold;">&#41;</span>
            <span style="color:#CC0066; font-weight:bold;">string</span> = quote.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#40;</span>\<span style="color:#006600; font-weight:bold;">&#123;</span>\<span style="color:#006600; font-weight:bold;">&#123;</span>.<span style="color:#9900CC;">*</span>?\<span style="color:#006600; font-weight:bold;">&#125;</span>\<span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>s<span style="color:#006600; font-weight:bold;">|</span>
              <span style="color:#006600; font-weight:bold;">&#40;</span>s =~ <span style="color:#006600; font-weight:bold;">/</span>\<span style="color:#006600; font-weight:bold;">&#123;</span>\<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? s : <span style="color:#996600;">`echo &quot;#{s.gsub('$', '<span style="color:#000099;">\$</span>')}&quot; | pig`</span>.<span style="color:#CC0066; font-weight:bold;">chomp</span>
            <span style="color:#9966CC; font-weight:bold;">end</span>
            translation.<span style="color:#CC0066; font-weight:bold;">sub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span>quote, <span style="color:#CC0066; font-weight:bold;">string</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#9966CC; font-weight:bold;">end</span>
        <span style="color:#9966CC; font-weight:bold;">end</span>
        fout.<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;#{key}:#{translation}&quot;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>P.S. Note to anyone that actually tries to use this: This is just a quick and dirty script and will probably require some modification to work in your situation. In particular it requires all the strings you want translated to be within double quotes.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-fourth/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Rails’ New I18n Support in Real Life: Part the Third</title>
		<link>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-third/</link>
		<comments>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-third/#comments</comments>
		<pubDate>Mon, 15 Dec 2008 15:14:58 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=53</guid>
		<description><![CDATA[What happens when you add a new string to your default locale file and forget about the other languages? Well, by default it&#8217;ll raise a MissingTranslationData and your users will see an ugly string the likes of &#8220;es-MX, marketing_interface, index, title&#8220;. Wouldn&#8217;t it be better to at least try and default to English? My guess [...]]]></description>
			<content:encoded><![CDATA[<p>What happens when you add a new string to your default locale file and forget about the other languages? Well, by default it&#8217;ll raise a MissingTranslationData and your users will see an ugly string the likes of &#8220;<em>es-MX, marketing_interface, index, title</em>&#8220;. Wouldn&#8217;t it be better to at least try and default to English? My guess is that most people would prefer to see the message in another language than some cryptic error message. And while we&#8217;re wishing, don&#8217;t you think the <em>localize</em> method shouldn&#8217;t die a noisy death when you happen to pass it a nil?</p>
<p>My solution? A custom I18n backend. I simply copy/pasted the code from the default &#8220;Simple&#8221; backend, tweaked a few lines and I was good to go!</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#008000; font-style:italic;"># In some file that gets sourced on startup, like maybe in your config/initializers directory</span>
<span style="color:#9966CC; font-weight:bold;">module</span> I18n
  <span style="color:#9966CC; font-weight:bold;">module</span> Backend
    <span style="color:#9966CC; font-weight:bold;">class</span> Moki <span style="color:#006600; font-weight:bold;">&lt;</span> Simple
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, key, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">raise</span> InvalidLocale.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>locale<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> locale.<span style="color:#0000FF; font-weight:bold;">nil</span>?
        <span style="color:#0000FF; font-weight:bold;">return</span> key.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>k<span style="color:#006600; font-weight:bold;">|</span> translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, k, options<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span> <span style="color:#9966CC; font-weight:bold;">if</span> key.<span style="color:#9900CC;">is_a</span>? <span style="color:#CC0066; font-weight:bold;">Array</span>
        reserved = <span style="color:#ff3333; font-weight:bold;">:scope</span>, <span style="color:#ff3333; font-weight:bold;">:default</span>
        count, scope, default = options.<span style="color:#9900CC;">values_at</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:count</span>, <span style="color:#006600; font-weight:bold;">*</span>reserved<span style="color:#006600; font-weight:bold;">&#41;</span>
        options.<span style="color:#9900CC;">delete</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:default</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        values = options.<span style="color:#9900CC;">reject</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#006600; font-weight:bold;">|</span>name, value<span style="color:#006600; font-weight:bold;">|</span> reserved.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
        entry = lookup<span style="color:#006600; font-weight:bold;">&#40;</span>locale, key, scope<span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#9966CC; font-weight:bold;">if</span> entry.<span style="color:#0000FF; font-weight:bold;">nil</span>?
          entry = default<span style="color:#006600; font-weight:bold;">&#40;</span>locale, default, options<span style="color:#006600; font-weight:bold;">&#41;</span>
          entry <span style="color:#006600; font-weight:bold;">||</span>= lookup<span style="color:#006600; font-weight:bold;">&#40;</span>I18n.<span style="color:#9900CC;">default_locale</span>, key, scope<span style="color:#006600; font-weight:bold;">&#41;</span>
          <span style="color:#CC0066; font-weight:bold;">raise</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">I18n::MissingTranslationData</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>locale, key, options<span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> entry.<span style="color:#0000FF; font-weight:bold;">nil</span>?
        <span style="color:#9966CC; font-weight:bold;">end</span>
        entry = pluralize<span style="color:#006600; font-weight:bold;">&#40;</span>locale, entry, count<span style="color:#006600; font-weight:bold;">&#41;</span>
        entry = interpolate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, entry, values<span style="color:#006600; font-weight:bold;">&#41;</span>
        entry
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
      <span style="color:#9966CC; font-weight:bold;">def</span> localize<span style="color:#006600; font-weight:bold;">&#40;</span>locale, object, <span style="color:#CC0066; font-weight:bold;">format</span> = <span style="color:#ff3333; font-weight:bold;">:default</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">nil</span> <span style="color:#9966CC; font-weight:bold;">if</span> object.<span style="color:#0000FF; font-weight:bold;">nil</span>?
        <span style="color:#CC0066; font-weight:bold;">raise</span> <span style="color:#CC00FF; font-weight:bold;">ArgumentError</span>, <span style="color:#996600;">&quot;Object must be a Date, DateTime or Time object. #{object.inspect} given.&quot;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> object.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:strftime</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        type = object.<span style="color:#9900CC;">respond_to</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:sec</span><span style="color:#006600; font-weight:bold;">&#41;</span> ? <span style="color:#996600;">'time'</span> : <span style="color:#996600;">'date'</span>
        formats = translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, <span style="color:#996600;">&quot;#{type}.formats&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span> = formats<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">to_sym</span><span style="color:#006600; font-weight:bold;">&#93;</span> <span style="color:#9966CC; font-weight:bold;">if</span> formats <span style="color:#006600; font-weight:bold;">&amp;&amp;</span> formats<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">to_sym</span><span style="color:#006600; font-weight:bold;">&#93;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span> = <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">dup</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/%</span>a<span style="color:#006600; font-weight:bold;">/</span>, translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, <span style="color:#996600;">&quot;date.abbr_day_names&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>object.<span style="color:#9900CC;">wday</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/%</span>A<span style="color:#006600; font-weight:bold;">/</span>, translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, <span style="color:#996600;">&quot;date.day_names&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>object.<span style="color:#9900CC;">wday</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/%</span>b<span style="color:#006600; font-weight:bold;">/</span>, translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, <span style="color:#996600;">&quot;date.abbr_month_names&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>object.<span style="color:#9900CC;">mon</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/%</span>B<span style="color:#006600; font-weight:bold;">/</span>, translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, <span style="color:#996600;">&quot;date.month_names&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#91;</span>object.<span style="color:#9900CC;">mon</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#CC0066; font-weight:bold;">gsub</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/%</span><span style="color:#CC0066; font-weight:bold;">p</span><span style="color:#006600; font-weight:bold;">/</span>, translate<span style="color:#006600; font-weight:bold;">&#40;</span>locale, <span style="color:#996600;">&quot;time.#{object.hour &lt; 12 ? :am : :pm}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> object.<span style="color:#9900CC;">respond_to</span>? <span style="color:#ff3333; font-weight:bold;">:hour</span>
        object.<span style="color:#9900CC;">strftime</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">format</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
I18n.<span style="color:#9900CC;">backend</span> = <span style="color:#6666ff; font-weight:bold;">I18n::Backend::Moki</span>.<span style="color:#9900CC;">new</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-third/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using Rails’ New I18n Support in Real Life: Part the Second</title>
		<link>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/</link>
		<comments>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 16:36:01 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=52</guid>
		<description><![CDATA[A few more thoughts on handling I18n for real projects.

Images
The way I handled images was pretty simple. Just added this application_helper:

  # Translated image tag
  def timage_tag&#40;source, options = &#123;&#125;&#41;
    image_tag&#40;&#34;#{I18n.locale}/#{source}&#34;, options&#41;
  end

Then I created a directory in public/images for each of the supported locales (e.g. public/images/en-US), put all [...]]]></description>
			<content:encoded><![CDATA[<p>A few more thoughts on handling I18n for real projects.</p>
<p><span id="more-52"></span></p>
<p><strong>Images</strong></p>
<p>The way I handled images was pretty simple. Just added this application_helper:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#008000; font-style:italic;"># Translated image tag</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> timage_tag<span style="color:#006600; font-weight:bold;">&#40;</span>source, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    image_tag<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{I18n.locale}/#{source}&quot;</span>, options<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Then I created a directory in public/images for each of the supported locales (e.g. public/images/en-US), put all the images with text in there and I was good to go.</p>
<hr />
<p><strong>Pagination</strong></p>
<p>Pagination was handled similarly with a helper to wrap the call to <a href="http://github.com/mislav/will_paginate/wikis">mislav&#8217;s will_paginate gem</a>:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#008000; font-style:italic;"># Translated will_paginate</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> twill_paginate<span style="color:#006600; font-weight:bold;">&#40;</span>collection = <span style="color:#0000FF; font-weight:bold;">nil</span>, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    will_paginate collection, <span style="color:#006600; font-weight:bold;">&#123;</span>:previous_label <span style="color:#006600; font-weight:bold;">=&gt;</span> t<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'constants.will_paginate.previous'</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#ff3333; font-weight:bold;">:next_label</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> t<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'constants.will_paginate.next'</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre># config/locales/en-US.yml
en-US:
  constants:
    will_paginate:
      previous: &quot;« Previous&quot;
      next: &quot;Next »&quot;</pre></div></div>

<hr />
<p><strong>activerecord</strong></p>
<p>Oh and another thing that really helped was using the human_name stuff <a href="http://iain.nl/2008/09/translating-activerecord/">built in</a> to activerecord. So, for example, everywhere I found an &#8220;Agent&#8221; in the text instead of an explicit call to <em>translate</em> I could just do <em>Agent.human_name</em>. And for each of Agent&#8217;s attributes I could do <em>Agent.human_attribute_name(&#8217;name&#8217;)</em>. And that even works when it&#8217;s not a real attribute, but just one of Agent&#8217;s public methods (or anything else for that matter). Plus it&#8217;ll work for your form labels too, once you install the <a href="git://github.com/iain/i18n_label.git">i18n label plugin</a>. (One caveat though: <em>label User, :username</em> won&#8217;t work. It has to be a <em>form_for(@user) do |f|</em> and then your <em>f.label :username</em> will show the human_attribute_name).</p>

<div class="wp_syntax"><div class="code"><pre>#config/locales/en-US.yml
en-US:
  activerecord:
    models:
      agent: &quot;Agent&quot;
    attributes:
      agent:
        name: &quot;Name&quot;
        some_calculated_value: &quot;Some Calculated Value&quot;</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Using Rails&#8217; New I18n Support in Real Life: Part the First</title>
		<link>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-first/</link>
		<comments>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-first/#comments</comments>
		<pubDate>Thu, 11 Dec 2008 17:26:12 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=51</guid>
		<description><![CDATA[Well, there are plenty of nice introductions and demos to Rails&#8217; slick new I18n features out there but I haven&#8217;t seen much on using it on a real decent-sized app. So I&#8217;ll share some of my thoughts on the subject.

Now a real application has more text that just hello_world and a couple paragraphs, so the [...]]]></description>
			<content:encoded><![CDATA[<p>Well, there are plenty of <a href="http://almosteffortless.com/2008/07/21/simple-localization-in-rails-22/">nice</a> <a href="http://railscasts.com/episodes/138-i18n">introductions</a> and <a href="http://i18n-demo.phusion.nl/">demos</a> to <a href="http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api">Rails&#8217; slick new I18n features</a> out there but I haven&#8217;t seen much on using it on a real decent-sized app. So I&#8217;ll share some of my thoughts on the subject.<br />
<span id="more-51"></span></p>
<p>Now a real application has more text that just hello_world and a couple paragraphs, so the question is how to organize it all in a way that makes sense. My first thought was to use controllers and actions, but that doesn&#8217;t work because sometimes the action doesn&#8217;t match the page you are rendering (for example when a create fails validation you probably render the new page even though <em>params[:action]</em> is still &#8216;create&#8217;). So instead I set my namespaces up to mimic my directory/filename structure as much as possible. And in order to make that a lot shorter and cleaner, I wrote a helper method (and put it in application_helper.rb) to help me out:<br />
<strong>UPDATE</strong>: Rails 2.3 added &#8220;<a href="http://guides.rubyonrails.org/i18n.html#lazy-lookup">lazy</a>&#8221; lookup so instead of the ugly __FILE__ stuff you can just prepend a dot. e.g. &#8220;.title&#8221; I don&#8217;t think it woks in controllers though.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#008000; font-style:italic;"># Translate from file (I18n namespace set to file path)</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> tf<span style="color:#006600; font-weight:bold;">&#40;</span>file, key, options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    t<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{file.gsub(%r|#{RAILS_ROOT}/app/<span style="color:#000099;">\w</span>*/|, '').sub(/<span style="color:#000099;">\.</span>(.*)$/, '').gsub('/', '.')}.#{key}&quot;</span>, options<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>So now any page that starts with a title looks like this:</p>

<div class="wp_syntax"><div class="code"><pre>  &lt;h1&gt;&lt;%= tf __FILE__, &quot;title&quot; %&gt;&lt;/h1&gt;</pre></div></div>

<p>And I can also use it in my controllers (as long as I <em>include ApplicationHelper</em>):</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#9966CC; font-weight:bold;">def</span> create
    <span style="color:#0066ff; font-weight:bold;">@agent</span> = Agent.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:agent</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> <span style="color:#0066ff; font-weight:bold;">@agent</span>.<span style="color:#9900CC;">save</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = tf<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span>, <span style="color:#996600;">'create_s'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      redirect_to documents_url
    <span style="color:#9966CC; font-weight:bold;">else</span>
      flash<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:notice</span><span style="color:#006600; font-weight:bold;">&#93;</span> = tf<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span>, <span style="color:#996600;">'create_f'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      render <span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'new'</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And my <em>config/locales/en-US.yml</em> might look like this:</p>

<div class="wp_syntax"><div class="code"><pre>en-US:
  agent_interface:
    agents_controller:
      create_s: &quot;Agent was successfully created.&quot;
      create_f: &quot;Error creating agent.&quot;
    agents:
      new:
        title: &quot;Create a new Agent&quot;
      show:
        title: &quot;Showing Agent&quot;
      _form:
        legend: &quot;Agent Information&quot;
  layouts:
    agent_interface:
      agent_interface:
        login: &quot;Log In&quot;
        logout: &quot;Log Out&quot;</pre></div></div>

<p>I like this method because not only does it work for the simple cases shown above but it also works great with layouts and partials and helpers.</p>
<p>I think it also helps to set some conventions for yourself. At first I started naming things with numbers (p1, p2, etc) but then I realized that makes views very cryptic to understand. So instead I tried to pick translation keys that explained the text a little better. And then tried to reuse those names when applicable. For instance, quite a few pages have a title, intro, legend, submit, etc. For flash messages I used the action name with an _s appended for successes and _f for failures. In general I tried to be as consistent as possible.</p>
<p>In future posts I&#8217;ll talk about how I <a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-second/">handled images</a>, some <a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-third/">I18n customizations</a> and how I <a href="http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-fourth/">checked</a> for translation coverage.</p>
<p>P.S. I think it&#8217;s pretty ugly to have all those redundant __FILE__s every time I call the helper, but I couldn&#8217;t find a good way to get the filename of the file where the method was first called. I tried playing with the stack trace from <code>caller</code> but it got confused on partials and layouts, and I didn&#8217;t have the time to find a better way.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/using-rails-new-i18n-support-in-real-life-part-the-first/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Rails Utility Methods</title>
		<link>http://www.mokisystems.com/blog/rails-utility-methods/</link>
		<comments>http://www.mokisystems.com/blog/rails-utility-methods/#comments</comments>
		<pubDate>Mon, 20 Oct 2008 17:26:47 +0000</pubDate>
		<dc:creator>Daniel</dc:creator>
				<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=41</guid>
		<description><![CDATA[Browsing the Rails API I found a few methods I wish I&#8217;d known about earlier.
current_page? in ActionView::Helpers::UrlHelper returns &#8220;true if the current request URI was generated by the given options.&#8221;

  current_page?&#40;:action =&#62; 'process'&#41;
  # =&#62; false
&#160;
  current_page?&#40;:action =&#62; 'checkout'&#41;
  # =&#62; true

reverse_merge! in ActiveSupport::CoreExtensions::Hash::ReverseMerge &#8220;allows for reverse merging where its the [...]]]></description>
			<content:encoded><![CDATA[<p>Browsing the <a href="http://api.rubyonrails.com/">Rails API</a> I found a few methods I wish I&#8217;d known about earlier.</p>
<p><strong>current_page?</strong> in ActionView::Helpers::UrlHelper returns &#8220;true if the current request URI was generated by the given options.&#8221;</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  current_page?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'process'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;"># =&gt; false</span>
&nbsp;
  current_page?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:action</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">'checkout'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#008000; font-style:italic;"># =&gt; true</span></pre></div></div>

<p><strong>reverse_merge!</strong> in ActiveSupport::CoreExtensions::Hash::ReverseMerge &#8220;allows for reverse merging where its the keys in the calling hash that wins over those in the other_hash.&#8221;</p>
<p>So now instead of</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#9966CC; font-weight:bold;">def</span> setup<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    options = <span style="color:#006600; font-weight:bold;">&#123;</span>:income <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0</span>, <span style="color:#ff3333; font-weight:bold;">:expenses</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">merge</span><span style="color:#006600; font-weight:bold;">&#40;</span>options<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I can do</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#9966CC; font-weight:bold;">def</span> setup<span style="color:#006600; font-weight:bold;">&#40;</span>options = <span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    options.<span style="color:#9900CC;">reverse_merge</span>! <span style="color:#ff3333; font-weight:bold;">:income</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0</span>, <span style="color:#ff3333; font-weight:bold;">:expenses</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">0</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>And with ActiveSupport::CoreExtensions::String::Conversions I can stop using the PHP feeling</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#CC00FF; font-weight:bold;">Date</span>.<span style="color:#9900CC;">parse</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;10/20/2008&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span></pre></div></div>

<p>to the more rubyish</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">  <span style="color:#996600;">&quot;10/20/2008&quot;</span>.<span style="color:#9900CC;">to_date</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/rails-utility-methods/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Add Markers to a Google Map With Ruby on Rails and JSON</title>
		<link>http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/</link>
		<comments>http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/#comments</comments>
		<pubDate>Thu, 25 Sep 2008 21:23:45 +0000</pubDate>
		<dc:creator>Wes Bangerter</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby on Rails]]></category>

		<guid isPermaLink="false">http://www.mokisystems.com/blog/?p=27</guid>
		<description><![CDATA[This tutorial will guide you through creating a map using the Google Maps API that will be dynamically populated with markers as the user zooms or scrolls around the map.
For this example, we&#8217;re going to create and use a generic Location model.
Geocoding Your Addresses
Geocoding will translate an address into its approximate latitude and longitude.
We&#8217;ll use [...]]]></description>
			<content:encoded><![CDATA[<p>This tutorial will guide you through creating a map using the Google Maps API that will be dynamically populated with markers as the user zooms or scrolls around the map.</p>
<p>For this example, we&#8217;re going to create and use a generic <code>Location</code> model.</p>
<h3>Geocoding Your Addresses</h3>
<p>Geocoding will translate an address into its approximate latitude and longitude.</p>
<p>We&#8217;ll use <a href="http://geokit.rubyforge.org/">GeoKit</a>, a Ruby on Rails plugin to geocode our addresses. Install it with:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">script<span style="color: #000000; font-weight: bold;">/</span>plugin <span style="color: #c20cb9; font-weight: bold;">install</span> svn:<span style="color: #000000; font-weight: bold;">//</span>rubyforge.org<span style="color: #000000; font-weight: bold;">/</span>var<span style="color: #000000; font-weight: bold;">/</span>svn<span style="color: #000000; font-weight: bold;">/</span>geokit<span style="color: #000000; font-weight: bold;">/</span>trunk</pre></div></div>

<p>Follow the instructions to obtain and install your own Google API key.</p>
<p>Generate the model, controller and views for our map locations:</p>

<div class="wp_syntax"><div class="code"><pre class="bash">script<span style="color: #000000; font-weight: bold;">/</span>generate scaffold location name:string address:string city:string \
state:string <span style="color: #c20cb9; font-weight: bold;">zip</span>:string</pre></div></div>

<p>We also need to edit the migration file for this model and add fields for the location&#8217;s latitude and longitude:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby">t.<span style="color:#9900CC;">decimal</span> <span style="color:#ff3333; font-weight:bold;">:lat</span>, <span style="color:#ff3333; font-weight:bold;">:precision</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">15</span>, <span style="color:#ff3333; font-weight:bold;">:scale</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">12</span>
t.<span style="color:#9900CC;">decimal</span> <span style="color:#ff3333; font-weight:bold;">:lng</span>, <span style="color:#ff3333; font-weight:bold;">:precision</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">15</span>, <span style="color:#ff3333; font-weight:bold;">:scale</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">12</span></pre></div></div>

<p>Replace the code in <code>app/models/location.rb</code> with:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> Location <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  acts_as_mappable
&nbsp;
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:name</span>, <span style="color:#ff3333; font-weight:bold;">:address</span>, <span style="color:#ff3333; font-weight:bold;">:city</span>, <span style="color:#ff3333; font-weight:bold;">:state</span>, <span style="color:#ff3333; font-weight:bold;">:zip</span>, <span style="color:#ff3333; font-weight:bold;">:lat</span>, <span style="color:#ff3333; font-weight:bold;">:lng</span>
  before_validation_on_create <span style="color:#ff3333; font-weight:bold;">:geocode_address</span>
&nbsp;
  private
    <span style="color:#9966CC; font-weight:bold;">def</span> geocode_address
      geo=<span style="color:#6666ff; font-weight:bold;">GeoKit::Geocoders::MultiGeocoder</span>.<span style="color:#9900CC;">geocode</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{address} #{city} #{state} #{zip}&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      errors.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:address</span>, <span style="color:#996600;">&quot;Could not Geocode address&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> !geo.<span style="color:#9900CC;">success</span>
      <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">lat</span>, <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">lng</span> = geo.<span style="color:#9900CC;">lat</span>,geo.<span style="color:#9900CC;">lng</span> <span style="color:#9966CC; font-weight:bold;">if</span> geo.<span style="color:#9900CC;">success</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>That&#8217;s all there is to geocoding, now any time we create a Location it will automatically be assigned a latitude and longitude.</p>
<h3>Adding the Google Map</h3>
<p>In <code>app/views/locations/index.html.erb</code> add:</p>

<div class="wp_syntax"><div class="code"><pre class="css">&lt;div id=<span style="color: #ff0000;">&quot;map&quot;</span> style=<span style="color: #ff0000;">&quot;width: 890px; height: 600px;&quot;</span>&gt;&lt;/div&gt;</pre></div></div>

<p>And in <code>app/views/controllers/locations_controller.rb</code>, change the index action to:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#008000; font-style:italic;"># GET /locations</span>
<span style="color:#008000; font-style:italic;"># GET /locations.xml</span>
<span style="color:#008000; font-style:italic;"># GET /locations.js</span>
<span style="color:#9966CC; font-weight:bold;">def</span> index
  respond_to <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>format<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">html</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#0066ff; font-weight:bold;">@locations</span> = Location.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">xml</span>  <span style="color:#006600; font-weight:bold;">&#123;</span> render <span style="color:#ff3333; font-weight:bold;">:xml</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@locations</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
    <span style="color:#CC0066; font-weight:bold;">format</span>.<span style="color:#9900CC;">js</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      ne = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:ne</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">collect</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>e<span style="color:#006600; font-weight:bold;">|</span>e.<span style="color:#9900CC;">to_f</span><span style="color:#006600; font-weight:bold;">&#125;</span>  
      sw = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:sw</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#CC0066; font-weight:bold;">split</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">','</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">collect</span><span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#006600; font-weight:bold;">|</span>e<span style="color:#006600; font-weight:bold;">|</span>e.<span style="color:#9900CC;">to_f</span><span style="color:#006600; font-weight:bold;">&#125;</span>
      <span style="color:#0066ff; font-weight:bold;">@locations</span> = Location.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:limit</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">100</span>, <span style="color:#ff3333; font-weight:bold;">:bounds</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span>sw, ne<span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      render <span style="color:#ff3333; font-weight:bold;">:json</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@locations</span>.<span style="color:#9900CC;">to_json</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The index action will now respond to javascript requests with a JSON object containing the first 100 Locations inside of the map boundaries.</p>
<p>In your layout file, add this code inside of the <code>&lt;head&gt;</code> tag:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby"><span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@locations</span>.<span style="color:#9900CC;">blank</span>? <span style="color:#006600; font-weight:bold;">%&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;</span>script
    src=<span style="color:#996600;">&quot;http://maps.google.com/maps?file=api&amp;v=2.x&amp;key=&lt;%= GeoKit::Geocoders::google -%&gt;&quot;</span>
    type=<span style="color:#996600;">&quot;text/javascript&quot;</span><span style="color:#006600; font-weight:bold;">&gt;&lt;/</span>script<span style="color:#006600; font-weight:bold;">&gt;</span>
  <span style="color:#006600; font-weight:bold;">&lt;%</span>= javascript_include_tag <span style="color:#996600;">'prototype'</span>, <span style="color:#996600;">'maps'</span> <span style="color:#006600; font-weight:bold;">%&gt;</span>
<span style="color:#006600; font-weight:bold;">&lt;%</span> <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">%&gt;</span></pre></div></div>

<p>And finally, create a <code>public/javascripts/maps.js</code> file with this code:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript">window.<span style="color: #000066;">onunload</span> <span style="color: #339933;">=</span> GUnload<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> map<span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> markers <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Event.<span style="color: #006600;">observe</span><span style="color: #009900;">&#40;</span>window<span style="color: #339933;">,</span> <span style="color: #3366CC;">'load'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>GBrowserIsCompatible<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    map <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> GMap2<span style="color: #009900;">&#40;</span>document.<span style="color: #006600;">getElementById</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;map&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #006600; font-style: italic;">// Center the map on the US</span>
    map.<span style="color: #006600;">setCenter</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> GLatLng<span style="color: #009900;">&#40;</span><span style="color: #CC0000;">37.731145</span><span style="color: #339933;">,</span><span style="color: #CC0000;">-97.326092</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><span style="color: #CC0000;">4</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    GEvent.<span style="color: #006600;">addListener</span><span style="color: #009900;">&#40;</span>map<span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;moveend&quot;</span><span style="color: #339933;">,</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>updateMap<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    map.<span style="color: #006600;">addControl</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> GLargeMapControl<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    map.<span style="color: #006600;">addControl</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">new</span> GMapTypeControl<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    updateMap<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> updateMap<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> bounds <span style="color: #339933;">=</span> map.<span style="color: #006600;">getBounds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> southWest <span style="color: #339933;">=</span> bounds.<span style="color: #006600;">getSouthWest</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> northEast <span style="color: #339933;">=</span> bounds.<span style="color: #006600;">getNorthEast</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Send an AJAX request for our locations</span>
  <span style="color: #003366; font-weight: bold;">new</span> Ajax.<span style="color: #006600;">Request</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/locations.js'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
    method<span style="color: #339933;">:</span><span style="color: #3366CC;">'get'</span><span style="color: #339933;">,</span>
    parameters<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>sw<span style="color: #339933;">:</span> southWest.<span style="color: #006600;">toUrlValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ne<span style="color: #339933;">:</span> northEast.<span style="color: #006600;">toUrlValue</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
    onSuccess<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>transport<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      <span style="color: #006600; font-style: italic;">// Remove markers outside of our maps boundaries.</span>
      <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>markers.<span style="color: #006600;">length</span> <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        removeMarkersOutsideOfMapBounds<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// Add our new markers to the map (unless they are already on the map.)</span>
      <span style="color: #003366; font-weight: bold;">var</span> json <span style="color: #339933;">=</span> transport.<span style="color: #006600;">responseText</span>.<span style="color: #006600;">evalJSON</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      json.<span style="color: #006600;">each</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>i<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        id <span style="color: #339933;">=</span> i.<span style="color: #006600;">location</span>.<span style="color: #006600;">id</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span>markers<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span> <span style="color: #339933;">||</span> markers<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span> <span style="color: #339933;">==</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
          <span style="color: #006600; font-style: italic;">// Marker doesnt exist, add it.</span>
          markers<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> createMarker<span style="color: #009900;">&#40;</span>i.<span style="color: #006600;">location</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          map.<span style="color: #006600;">addOverlay</span><span style="color: #009900;">&#40;</span>markers<span style="color: #009900;">&#91;</span>id<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>      
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> createMarkerClickHandler<span style="color: #009900;">&#40;</span>marker<span style="color: #339933;">,</span> location<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    marker.<span style="color: #006600;">openInfoWindowHtml</span><span style="color: #009900;">&#40;</span>
      <span style="color: #3366CC;">'&lt;div&gt;&lt;strong&gt;'</span> <span style="color: #339933;">+</span> location.<span style="color: #000066;">name</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&lt;/strong&gt;&lt;br/&gt; '</span> <span style="color: #339933;">+</span>
      location.<span style="color: #006600;">address</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&lt;br/&gt;'</span> <span style="color: #339933;">+</span> location.<span style="color: #006600;">city</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">', '</span> <span style="color: #339933;">+</span>
      location.<span style="color: #006600;">state</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">' '</span> <span style="color: #339933;">+</span> location.<span style="color: #006600;">zip</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">'&lt;/div&gt;'</span>
    <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> createMarker<span style="color: #009900;">&#40;</span>location<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> latlng <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> GLatLng<span style="color: #009900;">&#40;</span>location.<span style="color: #006600;">lat</span><span style="color: #339933;">,</span> location.<span style="color: #006600;">lng</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> marker <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> GMarker<span style="color: #009900;">&#40;</span>latlng<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #003366; font-weight: bold;">var</span> handler <span style="color: #339933;">=</span> createMarkerClickHandler<span style="color: #009900;">&#40;</span>marker<span style="color: #339933;">,</span> location<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  GEvent.<span style="color: #006600;">addListener</span><span style="color: #009900;">&#40;</span>marker<span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;click&quot;</span><span style="color: #339933;">,</span> handler<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">return</span> marker<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> removeMarkersOutsideOfMapBounds<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span>i <span style="color: #000066; font-weight: bold;">in</span> markers<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>i <span style="color: #339933;">&gt;</span> <span style="color: #CC0000;">0</span> <span style="color: #339933;">&amp;&amp;</span> markers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">&amp;&amp;</span> <span style="color: #339933;">!</span>map.<span style="color: #006600;">getBounds</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006600;">containsLatLng</span><span style="color: #009900;">&#40;</span>markers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #006600;">getLatLng</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      map.<span style="color: #006600;">removeOverlay</span><span style="color: #009900;">&#40;</span>markers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      markers<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <code>updateMap()</code> function is run after the page initially loads and each time the user moves or zooms the map. It sends an AJAX request to the server with the maps boundaries, and the server returns a JSON object of the locations within those boundaries. After it receives the JSON object, it will add new locations to the map (it skips locations that have already been mapped) and removes locations that are no longer within the visible map boundaries.</p>
<p>A sample app containing all of the code can be downloaded here: <a href="/blog/wp-content/uploads/2008/09/map-sample-code.zip">map-sample-code.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.mokisystems.com/blog/add-markers-to-a-google-map-with-ruby-on-rails-and-json/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
