<?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>Geoff Evason &#187; rails</title>
	<atom:link href="http://geoff.evason.name/tag/rails/feed/" rel="self" type="application/rss+xml" />
	<link>http://geoff.evason.name</link>
	<description></description>
	<lastBuildDate>Mon, 03 May 2010 01:22:04 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Nested has_many: through in Rails (or how to do a 3 table join)</title>
		<link>http://geoff.evason.name/2010/04/23/nested-has_many-through-in-rails-or-how-to-do-a-3-table-join/</link>
		<comments>http://geoff.evason.name/2010/04/23/nested-has_many-through-in-rails-or-how-to-do-a-3-table-join/#comments</comments>
		<pubDate>Fri, 23 Apr 2010 10:17:33 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[has_many]]></category>
		<category><![CDATA[nested]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[through]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=201</guid>
		<description><![CDATA[Today I came across a problem that I would have expected would work in Rails (2.3.5), but doesn&#8217;t.  I wanted to use a has_many :through relationship on a association that was itself a has_many :through.
Here is an example.  Let&#8217;s say I have Group class, which has many users through memberships.  Further, a [...]]]></description>
			<content:encoded><![CDATA[<p>Today I came across a problem that I would have expected would work in Rails (2.3.5), but doesn&#8217;t.  I wanted to use a has_many :through relationship on a association that was itself a has_many :through.</p>
<p>Here is an example.  Let&#8217;s say I have Group class, which has many users through memberships.  Further, a user has many comments.  What I want is a simple way to get all the comments that were made by users in a group.</p>
<pre><code class="ruby">
class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, :through => :memberships

  # This is what I would like to do, but this does not work!
  # has_many :comments, :through => :users
end

class User < ActiveRecord::Base
  has_many :comments
  has_many :memberships
  has_many :groups, :through => :memberships
end

class Comment <  ActiveRecord::Base
  belongs_to :user
  has_many :likes

  named_scope :approved, :conditions => {:approved => true}
end

</code></pre>
<p>What I <strong>want<strong> is to be able to call</p>
<pre><code class="ruby">
  @group = Group.find(params[:id])
  @comments = @group.comments.approved.find(:all, :include => :likes)
</code></pre>
<hr />
<p><strong>Option #1 : Includes</strong> : use includes when loading the group so I can eager load the comments. Then I can collect them:</p>
<pre><code class="ruby">
  @group = Group.find(params[:id], :include => {:users, :comments})
  @comments = @group.users.map{|u| u.comments}.flatten
</code></pre>
<p><strong>Problems with Option #1</strong> :  First, it is inefficient.  If I don&#8217;t use the user objects anywhere, I&#8217;m loading them for nothing.  Second, I can&#8217;t use pagination or other filters easily on the comments association.</p>
<hr />
<p><strong>Option #2 : find_by_sql </strong>  : use a method on Group to load up comments, like so:</p>
<pre><code class="ruby">
class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, :through => :memberships

  # This is what I would like to do, but this does not work!
  # has_many :comments, :through => :users

  def comments
    # Use a 3 table sql join to load the comments for all users in this group.
    Comment.find_by_sql("
             SELECT c.* FROM comments c
               INNER JOIN users u ON u.id = c.user_id
                 INNER JOIN memberships m ON m.user_id = u.id
             WHERE m.group_id = #{id}")
  end
end
</code></pre>
<p><strong>Problems with Option #2</strong> :   You can&#8217;t do eager loading, pagination, or use any named scopes on the comments class.  So, if I wanted to load on &#8216;approved&#8217; comments I&#8217;d have to write another method. boo.</p>
<hr />
<p><strong>Option #3 : named_scope + method </strong>  : use a named_scope on Comment and a method on Group so that i can make the calls that I want to&#8230;</p>
<pre><code class="ruby">
class Group < ActiveRecord::Base
  has_many :memberships
  has_many :users, :through => :memberships

  # This is what I would like to do, but this does not work!
  # has_many :comments, :through => :users

  # This lets us call the code in a nice looking way:
  # e.g. group.comments.approved
  def comments
    Comment.all_for_group(self)
  end
end

class Comment <  ActiveRecord::Base
  belongs_to :user
  has_many :likes

  named_scope :approved, :conditions => {:approved => true}

  # perform the 3 table join in a way that will
  # let us also call include and other filters.
  named_scope :all_for_group, lambda{ |group|
      {
        :joins      => {:users, :memberships},
        :conditions => {:memberships => {:group_id => group.id},
        :select     => "DISTINCT `comments`.*"
      }
    }
end
</code></pre>
<p>Option #3 is definitely the cleanest, and what I would recommend.  </p>
<p>I&#8217;m not sure if Rails 3 supports nested has_many :through, but 2.3.5 does not.  There is a <a href="http://dev.rubyonrails.org/ticket/6461">(very old) ticket</a> for Rails.  There is also a <a href="http://github.com/ianwhite/nested_has_many_through">nested has_many :through plugin</a> that is has an experimental branch for 2.3.x.  I don&#8217;t like using things that are &#8216;experimental&#8217;.  </p>
<p>The number of times you need to do multiple has_many :through associations should be fairly small.  If you are doing it a lot, you should probably reconsider your data model.  In most cases, a simple named_scope and method ought to do the trick for you like it did for me.</p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2010/04/23/nested-has_many-through-in-rails-or-how-to-do-a-3-table-join/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>IE Error : File Download on Rails Form Post</title>
		<link>http://geoff.evason.name/2010/03/22/ie-error-file-download-on-rails-form-post/</link>
		<comments>http://geoff.evason.name/2010/03/22/ie-error-file-download-on-rails-form-post/#comments</comments>
		<pubDate>Mon, 22 Mar 2010 04:41:36 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[ie]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=98</guid>
		<description><![CDATA[If you are using Rails, you many notice that some form posts from IE (6/7) result in IE asking you where you want to save a file, even if your response is supposed to be a redirect.  It took me a while to figure out what was happening here so thought I&#8217;d share it [...]]]></description>
			<content:encoded><![CDATA[<p>If you are using Rails, you many notice that some form posts from IE (6/7) result in IE asking you where you want to save a file, even if your response is supposed to be a redirect.  It took me a while to figure out what was happening here so thought I&#8217;d share it and save someone else the trouble.</p>
<p>It seems that IE doesn&#8217;t always send the correct accepts headers for a post. Rails (v2.3.5 at least) if it can&#8217;t find a matching format in a responds_to block, will just render the first response.</p>
<p>So, make sure you always order your responds_to blocks so that html is first.</p>
<pre><code class="ruby">def action
  # my action code
  respond_to do |format|
    # Always make sure HTML is first otherwise
    # you'll send a js response to IE!
    format.html { redirect_to '/' }
    format.js { }
  end
end
</code></pre>
<p>Otherwise, when you submit a form, Rails will render the js result, which IE sees as a file download.</p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2010/03/22/ie-error-file-download-on-rails-form-post/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Set Cookie in HTML Body for Rails 2.3.2</title>
		<link>http://geoff.evason.name/2009/05/26/set-cookie-in-html-body-for-rails-232/</link>
		<comments>http://geoff.evason.name/2009/05/26/set-cookie-in-html-body-for-rails-232/#comments</comments>
		<pubDate>Tue, 26 May 2009 04:33:55 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[cookies]]></category>
		<category><![CDATA[passenger]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=69</guid>
		<description><![CDATA[I recently upgraded an app to rails 2.3 and on many pages on my local machine the top of the HTML body included something like this:

Set-Cookie: _myapp_session_id=BAh7B...; path=/; HttpOnly

I couldn&#8217;t figure out what was happening until I found this forum post which explained that the problem was related to passenger 2.0.6.  To fix the [...]]]></description>
			<content:encoded><![CDATA[<p>I recently upgraded an app to rails 2.3 and on many pages on my local machine the top of the HTML body included something like this:</p>
<pre><code>
Set-Cookie: _myapp_session_id=BAh7B...; path=/; HttpOnly
</code></pre>
<p>I couldn&#8217;t figure out what was happening until I found <a href="http://railsforum.com/viewtopic.php?id=27180" title"rails 2.3 cookie in body">this forum post</a> which explained that the problem was related to passenger 2.0.6.  To fix the problem I just needed to update the version of passenger I was running.</p>
<p>To update passenger (on a mac) was pretty simple.  Just run the following 2 commands:</p>
<pre><code>
sudo gem install passenger
sudo passenger-install-apache2-module
</code></pre>
<p>Depending on how you set up your local apache instance, you may also need to update the config. I needed to update /etc/apache2/httpd.conf to</p>
<pre><code>
LoadModule passenger_module /Library/Ruby/Gems/1.8/gems/passenger-2.1.2/ext/apache2/mod_passenger.so
PassengerRoot /Library/Ruby/Gems/1.8/gems/passenger-2.1.2
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2009/05/26/set-cookie-in-html-body-for-rails-232/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Upgrading from Rails 2.2.2 to Rails 2.3.2</title>
		<link>http://geoff.evason.name/2009/05/04/upgrading-from-rails-222-to-rails-232/</link>
		<comments>http://geoff.evason.name/2009/05/04/upgrading-from-rails-222-to-rails-232/#comments</comments>
		<pubDate>Mon, 04 May 2009 11:32:44 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[2.3.2]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[upgrade]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=67</guid>
		<description><![CDATA[I recently upgraded one of my apps from Rails 2.2.2 to Rails 2.3.2.  It was actually a really easy upgrade, but there were  few little gotchas I had to watch out for, so I thought I&#8217;d share my experience.
Upgrading Rails
I imagine there is probably a better way to do this, but since I [...]]]></description>
			<content:encoded><![CDATA[<p>I recently upgraded one of my apps from Rails 2.2.2 to Rails 2.3.2.  It was actually a really easy upgrade, but there were  few little gotchas I had to watch out for, so I thought I&#8217;d share my experience.</p>
<p><strong>Upgrading Rails</strong></p>
<p>I imagine there is probably a better way to do this, but since I change the version of rails so infrequently I&#8217;m not sure.  (If there is a better way, please let me know). My flow is as follows:</p>
<p>Install the new version of the rails gems:</p>
<pre><code>
sudo gem install rails
</code></pre>
<p>Branch your app</p>
<pre><code>
git branch newrails
git co newrails
</code></pre>
<p>Remove the old version of frozen gems</p>
<pre><code>
git rm -rf vendor/rails
</code></pre>
<p>Update your config/environment.rb file to the new version of rails:</p>
<pre><code class='ruby'>
RAILS_GEM_VERSION = '2.3.2' unless defined? RAILS_GEM_VERSION
</code></pre>
<p>freeze the new gems</p>
<pre><code>
rake rails:freeze:gems
</code></pre>
<p>Please note, that if instead of installing the new gems and freezing them from your local gems, it looks as though you need to be careful if using rake rails:freeze:gems.  You can read more about it in the <a href="http://weblog.rubyonrails.org/2009/3/20/this-week-in-edge-rails" title="rails 2.3.2.1">official post</a> or in <a href="http://afreshcup.com/2009/03/18/rails-2321/" title="rails 2.3.2.1">this post</a> which I found more understandable.</p>
<p><strong>Testing Your App</strong></p>
<p>The first and most obvious error you will run into is this:</p>
<pre><code class='ruby'>
uninitialized constant ApplicationController
</code></pre>
<p>This is because as of <a href="http://guides.rubyonrails.org/2_3_release_notes.html#application-controller-renamed">Rails 2.3 application.rb is now application_controller.rb</a>.  To fix this just do</p>
<pre><code>
git mv app/controllers/application.rb app/controllers/application_controller.rb
</code></pre>
<p>The next error I got was</p>
<pre><code>
undefined method `relative_url_root' for #<actionController::Request:0x373adf4>
</code></pre>
<p>I narrowed this down to a stylesheet_link_tag call.  I got around this by updating the <a href="http://synthesis.sbecker.net/pages/asset_packager" title="asset packager">asset_packager</a> plugin, and updating HAML to 2.0.9.  By the way, if you&#8217;re not using asset packager, you should be.</p>
<p>That&#8217;s it!  It overall was a very easy upgrade that took much less time to test than my <a href="http://geoff.evason.name/2009/01/15/upgrading-an-app-from-rails-21-to-rails-222/">rails 2.1 to rails 2.2.2 upgrade</a>.</p>
<p>Here are <a href="http://giantrobots.thoughtbot.com/2009/4/15/rails-2-3-2-upgrade-gotchas">some other rails 2.3 gotchas</a> to watch out for courtesy of thoughtbot.</p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2009/05/04/upgrading-from-rails-222-to-rails-232/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Setting a Capistrano Variable from the Command Line</title>
		<link>http://geoff.evason.name/2009/03/27/setting-a-capistrano-variable-from-the-command-line/</link>
		<comments>http://geoff.evason.name/2009/03/27/setting-a-capistrano-variable-from-the-command-line/#comments</comments>
		<pubDate>Fri, 27 Mar 2009 00:57:46 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[capistrano]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=65</guid>
		<description><![CDATA[It took me a little while to find a solution for this, so I thought I&#8217;d post it.
I was cleaning some deployment dirs and wanted, just for this instance, to only leave 1 release as opposed to the 5 releases that capistrano leaves by default. Keep in mind this was across about 6 apps and [...]]]></description>
			<content:encoded><![CDATA[<p>It took me a little while to find a solution for this, so I thought I&#8217;d post it.</p>
<p>I was cleaning some deployment dirs and wanted, just for this instance, to only leave 1 release as opposed to the 5 releases that capistrano leaves by default. Keep in mind this was across about 6 apps and 2 stages for each.</p>
<p>Option 1: Add the following to the deploy.rb files:</p>
<pre><code class="ruby">
set :keep_releases, 1
</code></pre>
<p>That would require changing them all back afterwards.</p>
<p>Options 2: Set the capistrano variable from the command line:</p>
<pre><code class="ruby">
cap deploy:cleanup -s keep_releases=1
</code></pre>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2009/03/27/setting-a-capistrano-variable-from-the-command-line/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Domain Name Registration API Plugin for Rails</title>
		<link>http://geoff.evason.name/2009/02/26/domain-name-registration-api-plugin-for-rails/</link>
		<comments>http://geoff.evason.name/2009/02/26/domain-name-registration-api-plugin-for-rails/#comments</comments>
		<pubDate>Thu, 26 Feb 2009 00:55:50 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[domain name]]></category>
		<category><![CDATA[plugin]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[register]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=63</guid>
		<description><![CDATA[If you&#8217;ve ever had an app where you want to allow users to purchase a domain name, you&#8217;ve probably felt the pain of trying to interface to a registrar.  Although some have APIs, my search found that most were hard to interface to or poorly documented.  Many even required signing up as a partner (and [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever had an app where you want to allow users to purchase a domain name, you&#8217;ve probably felt the pain of trying to interface to a registrar.  Although some have APIs, my search found that most were hard to interface to or poorly documented.  Many even required signing up as a partner (and paying a big fee) before you could even get documenation.</p>
<p>After much searching and experimenting I decided to go with <a href="http://www.register.com">Register.com</a>&#8217;s XML api for my app.  They offered the best API, and the easiest signup path.</p>
<p>I bundled the main part of the interface into a rails plugin.  The plugin is stored on github: <a href="http://github.com/geoffevason/register-api/tree/master" title="register.com api for rails">http://github.com/geoffevason/register-api/tree/master</a></p>
<p>To install the plugin do this:</p>
<pre><code>
script/plugin install git://github.com/geoffevason/register-api.git
</code></pre>
<p>The plugin is of little value unless you have spoken to register.com and have received their API documentation.  You need to register as a partner (it&#8217;s free) and have the IP of your dev machine whitelisted for testing.</p>
<p>Most of the info on use is in the readme in the plugin.  You can call any of the Register.com API methods by calling Register::API.</p>
<pre><code class='ruby'>
# A call to the API looks like this
# Register::Api::Call(params)

# Example to check if the domain name google.com is available
Register::Api::Check( :tld => 'com', :sld => 'google' )
</code></pre>
<p>The plugin also contains a few helper methods and classes.  If all you want to do is let people search for an available domain, and purchase it, then everything you need is in these helpers.  Some important logic remains in my controllers, but if you have any questions, let me know.  geoff [a] evason.name</p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2009/02/26/domain-name-registration-api-plugin-for-rails/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Upgrading an app from Rails 2.1 to Rails 2.2.2</title>
		<link>http://geoff.evason.name/2009/01/15/upgrading-an-app-from-rails-21-to-rails-222/</link>
		<comments>http://geoff.evason.name/2009/01/15/upgrading-an-app-from-rails-21-to-rails-222/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 04:19:31 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=56</guid>
		<description><![CDATA[Here is a summary of a few of the problems I encountered while trying to upgrade an app from rails 2.1 to rails 2.2.2
Getting my dev code to run
First, to update the rails code:
 &#62; rake rails:freeze:gems

The first time I tried to run the app I got this error:
vendor/rails/activesupport/lib/active_support/dependencies.rb:445:in `load_missing_constant': uninitialized constant Inflector (NameError)

Accessing the inflector changes, so [...]]]></description>
			<content:encoded><![CDATA[<p>Here is a summary of a few of the problems I encountered while trying to upgrade an app from rails 2.1 to rails 2.2.2</p>
<h3>Getting my dev code to run</h3>
<p>First, to update the rails code:</p>
<pre><code> &gt; rake rails:freeze:gems
</code></pre>
<p>The first time I tried to run the app I got this error:</p>
<pre><code>vendor/rails/activesupport/lib/active_support/dependencies.rb:445:in `load_missing_constant': uninitialized constant Inflector (NameError)
</code></pre>
<div>Accessing the inflector changes, so as <a title="rails 2.2 inflector" href="http://railstic.com/2008/12/rails-22-inflector/">described here</a> you need update APP/config/initializers/inflector.rb so it looks like this:</div>
<pre><code class="ruby">ActiveSupport::Inflector.inflections do |inflect|
  ...
end
</code></pre>
<p>In my case, I was also using the <a title="active merchant" href="http://www.activemerchant.org/">ActiveMerchant plugin</a> which needed updating for the same reason</p>
<pre><code>script/plugin install git://github.com/Shopify/active_merchant.git --force
</code></pre>
<p>According to <a title="haml update for rails 2.2" href="http://gusg.us/code/ruby/rails-2_2-headaches-1">gusg.us</a>, HAML needs to be at 2.0.4.   I didn&#8217;t see any problems in my testing but I didn&#8217;t want to try my luck so I updated HAML too.</p>
<pre><code>sudo gem update haml</code></pre>
<p>update my environment.rb gem requirement</p>
<pre><code class="ruby">config.gem "haml", :version =&gt; "2.0.6"</code></pre>
<div>Then run</div>
<pre><code>rake gems:unpack:dependencies</code></pre>
<h3>Production</h3>
<p>While deploying to a staging server I got this error:</p>
<pre><code>initializer.rb:514:in `send': undefined method `cache_template_loading=' for ActionView::Base:Class (NoMethodError)</code></pre>
<p>As described <a href="http://railsforum.com/viewtopic.php?id=23648">here</a>, to fix this, just update your APP/config/environments/production.rb (and staging.rb) file by removing the following:</p>
<pre><code class="ruby">config.action_view.cache_template_loading</code></pre>
<p>Overall, it wasn&#8217;t too painful an upgrade&#8230;</p>
<p>I didn&#8217;t run rake rails:update. That may have fixed some of these things on it&#8217;s own, but my understanding was that that wasn&#8217;t needed anymore&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2009/01/15/upgrading-an-app-from-rails-21-to-rails-222/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Simple Currency Conversion Rate API Consumption For Ruby / Rails</title>
		<link>http://geoff.evason.name/2008/10/27/simple-currency-conversion-rate-api-consumption-for-ruby-rails/</link>
		<comments>http://geoff.evason.name/2008/10/27/simple-currency-conversion-rate-api-consumption-for-ruby-rails/#comments</comments>
		<pubDate>Mon, 27 Oct 2008 13:38:51 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[api]]></category>
		<category><![CDATA[currency]]></category>
		<category><![CDATA[rails]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=53</guid>
		<description><![CDATA[I had the need to consume some exchange rate data for an internal project so I began looking for an about. My searching found no api for Google Finance, Yahoo Finance, XE, or Oanda.  
Fortunately I found the currency converter from Xavier Media and their simple currency exchange rate xml API, which includes historical data [...]]]></description>
			<content:encoded><![CDATA[<p>I had the need to consume some exchange rate data for an internal project so I began looking for an about. My searching found no api for Google Finance, Yahoo Finance, XE, or Oanda. <img src='http://geoff.evason.name/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
<p>Fortunately I found the <a href="http://finance.xaviermedia.com/">currency converter from Xavier Media</a> and their simple <a href="http://forum.xaviermedia.com/xavier-finance-currency-exchange-rate-api-t10979.html">currency exchange rate xml API</a>, which includes historical data too. <img src='http://geoff.evason.name/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
<p>I put together an absolutely minimal lib to get the data I need.  I just needed the AU/US rate.  The xml provides all data as base to EUR, but with some simple math I can find the rate I need with reasonable accuracy.  In this case &#8216;accuracy&#8217; is based on spot checking it against the yahoo rates.</p>
<p>I thought it worth sharing in case others are looking for something similar.</p>
<p><strong>UPDATE:</strong> I changed the xml string below to better handle single digit date months. Xavier needs &#8216;01&#8242; instead of &#8216;1&#8242;</p>
<pre><code class="ruby">require "cgi"
require "uri"
require "net/https"
require "rexml/document"

module XavierMedia
  # Returns the exchange rate (AUD/USD) on the given date.
  def self.exchange_rate_on(date)
    url = URI.parse("http://api.finance.xaviermedia.com/api/#{date.year}/#{date.strftime("%m")}/#{date.strftime("%d")}.xml")

    resp = Net::HTTP.get(url)
    xml  = REXML::Document.new(resp)

    us_to_eur = 1.0
    au_to_eur = 1.0
    xml.elements.each("//exchange_rates/fx") { |el|
      if el.elements[1].text == "USD"
        us_to_eur = el.elements[2].text.to_f rescue 1.0
      end
      if el.elements[1].text == "AUD"
        au_to_eur = el.elements[2].text.to_f rescue 1.0
      end
    }

    return us_to_eur/au_to_eur
  end
end
</code></pre>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2008/10/27/simple-currency-conversion-rate-api-consumption-for-ruby-rails/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Rails Fragment Caching Slowness With Regex Expiry</title>
		<link>http://geoff.evason.name/2008/10/26/rails-fragment-caching-slowness-with-regex-expiry/</link>
		<comments>http://geoff.evason.name/2008/10/26/rails-fragment-caching-slowness-with-regex-expiry/#comments</comments>
		<pubDate>Sun, 26 Oct 2008 19:27:37 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[cache]]></category>
		<category><![CDATA[fragment]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[sweep regex]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=52</guid>
		<description><![CDATA[Fragment caching in rails works great.  We use it a lot for MomentVille and easily get most of our responses in under 150ms because it dramatically reduces teh number of queries we need to run for our most common actions.
I did notice some slowness recently though, and was quite confused.  The slowness only occurred on [...]]]></description>
			<content:encoded><![CDATA[<p>Fragment caching in rails works great.  We use it a lot for <a title="free wedding website" href="http://www.momentville.com">MomentVille</a> and easily get most of our responses in under 150ms because it dramatically reduces teh number of queries we need to run for our most common actions.</p>
<p>I did notice some slowness recently though, and was quite confused.  The slowness only occurred on our production servers. Our dev, test, and pre-production servers were all still fast.  I tried using <a title="rails performance" href="http://www.newrelic.com">new relic rpm service</a> to help pinpoint the problem, and while it does a great job in helping you track things, it didn&#8217;t help me narrow down the problem.</p>
<p>Ultimately I discovered that the problem had to do with how we clear the cache. For some actions we have to expire multiple fragments, so we used regex expiration.  Unfortunately, that is <a title="rails fragment expiry regex" href="http://gurge.com/blog/2007/02/04/rails-expire_fragmentregex-considered-harmful/">very slow</a>.  It seems that regex expiry compares your regex to each fragment stored, even if you think your regex looks like it&#8217;s targeting a directory.</p>
<p>Alexander Dymo had a <a title="rails fragment cache expiry regex" href="http://blog.pluron.com/2008/07/hell-is-paved-w.html">post about regex expiry of fragment caches in rails</a> that outlined a solution for him.  It helped guide me to a solution that works well for us.  OUr fragment caches are actually structured around the data as opposed to the actions, so related fragments are stored within sub directories.  When we need to clear a bunch at once, we just want to wipe out the whole directory.  So, I created a file called fragment_dir_expiration.rb and put it into my /config/initializers folder.  It looks like this:</p>
<pre><code class="ruby"># For rails 2.0 and lower</code></pre>
<pre><code class="ruby">module ActionController
  module Caching
    module Fragments

      #dir is the cache path relative to the cache root
      def expire_fragment_dir(dir, options = nil)
        return unless perform_caching
        self.class.benchmark("Expired fragments in dir : #{dir}") do
          ActionController::Base.cache_store.delete_fragment_dir(dir, options)
        end
      end

      class UnthreadedFileStore

        def delete_fragment_dir(dir, options = nil)
          path = @cache_path + dir
          return unless File.exist?(path) #it's ok to not have the cache dir
          search_dir(path) do |f|
            begin
              File.delete(f)
            rescue SystemCallError =&gt; e
              # If there's no cache, then there's nothing to complain about
            end
          end
        end

      end
    end
  end
end

</code></pre>
<p>When you want to call this you can call it from an observer with a call like this</p>
<pre><code class="ruby">class WidgetSweeper &lt; ActionController::Caching::Sweeper
  observe Widget
  def after_save(widget)
    # Expire all the fragments for the updated widget
    expire_fragment_dir("/widget/#{widget.id}/")
  end
end
</code></pre>
<p><strong><em>UPDATE: For rails 2.1 and above use the following:</em></strong></p>
<pre><code class="ruby">module ActionController
  module Caching
    module Fragments

      #dir is the cache path relative to the cache root
      def expire_fragment_dir(dir, options = nil)
        return unless perform_caching
        self.class.benchmark("Expired fragments in dir : #{dir}") do
          ActionController::Base.cache_store.delete_fragment_dir(dir, options)
        end
      end

    end
  end
end

module ActiveSupport
  module Cache
    class FileStore

      def delete_fragment_dir(dir, options = nil)
        path = @cache_path + dir
        return unless File.exist?(path) #it's ok to not have the cache dir
        search_dir(path) do |f|
          begin
            File.delete(f)
          rescue SystemCallError =&gt; e
            # If there's no cache, then there's nothing to complain about
          end
        end
      end
    end
  end
end
</code></pre>
<p> </p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2008/10/26/rails-fragment-caching-slowness-with-regex-expiry/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>My .bash_profile for git &amp; Rails</title>
		<link>http://geoff.evason.name/2008/08/19/my-bash_profile-for-git-rails/</link>
		<comments>http://geoff.evason.name/2008/08/19/my-bash_profile-for-git-rails/#comments</comments>
		<pubDate>Tue, 19 Aug 2008 20:20:19 +0000</pubDate>
		<dc:creator>Geoff</dc:creator>
				<category><![CDATA[tech]]></category>
		<category><![CDATA[.bash_profile]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[git]]></category>
		<category><![CDATA[prompt]]></category>
		<category><![CDATA[rails]]></category>
		<category><![CDATA[terminal]]></category>

		<guid isPermaLink="false">http://geoff.evason.name/?p=50</guid>
		<description><![CDATA[I&#8217;ve converted all of my projects from svn to git.  If you haven&#8217;t done so already, and can do it, I would recommend not waiting anymore.  It does make things better.  
I used to really like the visual representations available on svn (such as tortoise svn) and rarely used the command line for repository related [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve converted all of my projects from svn to git.  If you haven&#8217;t done so already, and can do it, I would recommend not waiting anymore.  It does make things better.  </p>
<p>I used to really like the visual representations available on svn (such as tortoise svn) and rarely used the command line for repository related things.  The way git works (in particular, not having to have a special &#8217;svn folder within each folder) makes managing files way easier.  The best way to learn is to check out the <a title="git peep code" href="http://peepcode.com/products/git">git peepcode</a>.  I borrowed some of the aliases below from the screencast.</p>
<p>Now that I&#8217;m on the command line more, I&#8217;ve created a .bash_profile to make my life easier.  It is full of nice goodies that I collected.  I figured that I&#8217;d share it with the world in case others find it helpful.  It includes:</p>
<ul>
<li>Updating the OSX Leopard terminal title bar (and potentially the tabs) to include the working directory</li>
<li>Updating the command prompt to include the current directory and the current git branch (if you&#8217;re in a git repo)</li>
<li>Lots of aliases to save myself keystrokes.</li>
</ul>
<pre><code>
# Get the name of the current git branc
function parse_git_branch {
  git branch --no-color 2&gt; /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/(\1)/'
}

# Update the command prompt to be &lt;user&gt;:&lt;current_directory&gt;(git_branch) &gt;
# Note that the git branch is given a special color
function set_my_prompt {
  PS1="\u:\w\e[1;34m\$(parse_git_branch)\e[m &gt; "
}

# Update the title for the terminal window to be the full working dir
function set_term_title
{
    local title="$1"
    if [[ -z "$title" ]]; then
        title="root"
    fi

    local tmpdir=~/Library/Caches/${FUNCNAME}_temp
    local cmdfile="$tmpdir/$title"

    # Set window title
    #echo -n -e "\e]0;${title}\a"
    echo -n -e "\e]0;${PWD#*/}\a"

   # Set tab title
   # This works by creating a process with the name of the working dir.  
   # So, the tab name doesn't stick if you start running a mongrel server <img src='http://geoff.evason.name/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' />
    if [[ -n ${CURRENT_TAB_TITLE_PID:+1} ]]; then
        kill $CURRENT_TAB_TITLE_PID
    fi
    mkdir -p $tmpdir
    ln /bin/sleep "$cmdfile"
    "$cmdfile" 10 &amp;
    CURRENT_TAB_TITLE_PID=$(jobs -x echo %+)
    disown %+
    kill -STOP $CURRENT_TAB_TITLE_PID
    command rm -f "$cmdfile"
}

set_my_prompt
PROMPT_COMMAND='set_term_title "${PWD##*/}"'

# Some aliases I find useful
alias gclb="git checkout -b"
alias gb="git branch"
alias gba="git branch -a"
alias gs="git status"
alias gca="git commit -a"
alias gcm="git commit -m"
alias gk="gitk --all &amp;"
alias ss="script/server"
alias ssp="script/server -p"
alias sr="script/runner"

</code></pre>
<p>Big credit goes <a title="osx leopard terminal title and tab naming" href="http://pseudogreen.org/blog/set_tab_names_in_leopard_terminal.htm">Christopher Stawarz</a> to the the tab &amp; title thing: l</p>
]]></content:encoded>
			<wfw:commentRss>http://geoff.evason.name/2008/08/19/my-bash_profile-for-git-rails/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
