<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss 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" version="2.0">

<channel>
	<title>almost effortless</title>
	
	<link>http://almosteffortless.com</link>
	<description>æ + internet = love</description>
	<pubDate>Tue, 22 Jul 2008 02:48:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.6</generator>
	<language>en</language>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/almosteffortless" type="application/rss+xml" /><item>
		<title>Simple Localization in Rails 2.2</title>
		<link>http://almosteffortless.com/2008/07/21/simple-localization-in-rails-22/</link>
		<comments>http://almosteffortless.com/2008/07/21/simple-localization-in-rails-22/#comments</comments>
		<pubDate>Mon, 21 Jul 2008 19:34:37 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/?p=682</guid>
		<description><![CDATA[I've been staying on the sidelines when it comes to localization in Rails for a while now, but I couldn't help getting excited about the upcoming native support in Rails 2.2. So, with some guidance from the Rails i18n team, I decided to give things a try. 
I've been extremely pleased with the results so [...]]]></description>
			<content:encoded><![CDATA[<p>I've been staying on the sidelines when it comes to localization in Rails for a while now, but I couldn't help getting excited about the <a href="http://weblog.rubyonrails.org/2008/7/20/internationalization-in-edge-rails-and-more">upcoming</a> <a href="http://www.artweb-design.de/2008/7/18/finally-ruby-on-rails-gets-internationalized">native</a> <a href="http://www.artweb-design.de/2008/7/18/the-ruby-on-rails-i18n-core-api">support</a> in Rails 2.2. So, with some <a href="http://groups.google.com/group/rails-i18n/browse_thread/thread/2bcddef0d903e3a2">guidance from the Rails i18n team</a>, I decided to give things a try. </p>
<p>I've been extremely pleased with the results so far, but I'm all ears if anyone would like to offer suggestions on how to better achieve basic localization for a Rails app. Here's where I'm at so far in a kind of how-to format. This is all plugin-free, using only what's available in core. I expect that plugins will be coming out to add features and functionality, but you can accomplish quite a bit without any extras. </p>
<p>You can try to follow along, or just get the gist be reading through the steps. As noted in the comments, this is just a proof of concept, is not secure, and shouldn't be used in production as-is.</p>
<p>1. Make a new Rails app and freeze edge:</p>
<pre>&nbsp;
~ $ rails i18n
~ $ cd i18n
~ $ rake rails:freeze:edge
&nbsp;</pre>
<p>2. Make a couple of translation stores (files) in lib/locale directory:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># lib/locale/en-US.rb</span>
I18n.<span style="color:#9900CC;">store_translations</span> <span style="color:#996600;">'en-US'</span>,
<span style="color:#ff3333; font-weight:bold;">:hello_world</span> =&gt; <span style="color:#996600;">&quot;Hello World&quot;</span>,
<span style="color:#ff3333; font-weight:bold;">:hello_flash</span> =&gt; <span style="color:#996600;">&quot;Hello Flash&quot;</span>
&nbsp;
<span style="color:#008000; font-style:italic;">#lib/locale/pirate.rb</span>
I18n.<span style="color:#9900CC;">store_translations</span> <span style="color:#996600;">'pirate'</span>,
<span style="color:#ff3333; font-weight:bold;">:hello_world</span> =&gt; <span style="color:#996600;">&quot;Ahoy World&quot;</span>,
<span style="color:#ff3333; font-weight:bold;">:hello_flash</span> =&gt; <span style="color:#996600;">&quot;Ahoy Flash&quot;</span>
&nbsp;</pre>
<p>3. Set I18n.locale with a before_filter:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># app/controllers/application.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController &lt; <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
&nbsp;
  before_filter <span style="color:#ff3333; font-weight:bold;">:set_locale</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> set_locale
    locale = params<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:locale</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#996600;">'en-US'</span>
    I18n.<span style="color:#9900CC;">locale</span> = locale
    I18n.<span style="color:#9900CC;">populate</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      <span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">&quot;lib/locale/#{locale}.rb&quot;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>4. Create a "t" convenience method (I thought this was going to be there automagically?):</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># app/helpers/application_helper.rb</span>
<span style="color:#9966CC; font-weight:bold;">module</span> ApplicationHelper
  <span style="color:#9966CC; font-weight:bold;">def</span> t<span style="color:#006600; font-weight:bold;">&#40;</span>*args<span style="color:#006600; font-weight:bold;">&#41;</span>
    translate<span style="color:#006600; font-weight:bold;">&#40;</span>*args<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>
&nbsp;</pre>
<p>7. Make a controller and route to test things out, using symbols from your translation for user messages:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># config/routes.rb</span>
<span style="color:#6666ff; font-weight:bold;">ActionController::Routing::Routes</span>.<span style="color:#9900CC;">draw</span> <span style="color:#9966CC; font-weight:bold;">do</span> |map|
  map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> =&gt; <span style="color:#996600;">'home'</span>, <span style="color:#ff3333; font-weight:bold;">:action</span> =&gt; <span style="color:#996600;">'index'</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># app/controllers/home_controller.rb</span>
<span style="color:#9966CC; font-weight:bold;">class</span> HomeController &lt; ApplicationController
  <span style="color:#9966CC; font-weight:bold;">def</span> index
    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> = <span style="color:#ff3333; font-weight:bold;">:hello_flash</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>6. Create a view using symbols for user messages and use the "t" helper to translate:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># app/views/home/index.html.erb</span>
&lt;h1&gt;&lt;%=t <span style="color:#ff3333; font-weight:bold;">:hello_world</span> %&gt;&lt;/h1&gt;
&nbsp;
&lt;%=t 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> %&gt;
&nbsp;
&lt;%= link_to <span style="color:#996600;">'en-US'</span>, root_path<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:locale</span> =&gt; <span style="color:#996600;">'en-US'</span><span style="color:#006600; font-weight:bold;">&#41;</span> %&gt; <span style="color:#9966CC; font-weight:bold;">or</span>
&lt;%= link_to <span style="color:#996600;">'pirate'</span>, root_path<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:locale</span> =&gt; <span style="color:#996600;">'pirate'</span><span style="color:#006600; font-weight:bold;">&#41;</span> %&gt;
&nbsp;</pre>
<p>6. Fire up the old script/server and check it out:</p>
<pre>&nbsp;
~ $ script/server
&nbsp;</pre>
<p><img alt="" src="/files/i18n-en.png" /></p>
<p><img alt="" src="/files/i18n-pirate.png" /></p>
<p>I think that about covers it. Of course, this is a very simple example, but it should cover the basics well enough to get started. Please let me know if you have any ideas about how to simplify/improve this, and thanks again to the Rails <a href="http://groups.google.com/group/rails-i18n">i18n team</a> for all of their work - everything looks great so far!</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/07/21/simple-localization-in-rails-22/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Migrate to the Rails Default Time Zones</title>
		<link>http://almosteffortless.com/2008/06/03/migrate-to-the-rails-default-time-zones/</link>
		<comments>http://almosteffortless.com/2008/06/03/migrate-to-the-rails-default-time-zones/#comments</comments>
		<pubDate>Tue, 03 Jun 2008 23:02:49 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/?p=680</guid>
		<description><![CDATA[I was recently upgrading my open-source app, El Dorado, up to Rails 2.1 and decided to switch over to the default time zones provided by the Rails. I'm not sure where I picked up the time zone definitions I was using before, but they were things like "US/Central" as opposed to "Central Time (US &#038; [...]]]></description>
			<content:encoded><![CDATA[<p>I was recently upgrading my open-source app, <a href="http://almosteffortless.com/eldorado">El Dorado</a>, up to <a href="http://weblog.rubyonrails.org/2008/6/1/rails-2-1-time-zones-dirty-caching-gem-dependencies-caching-etc">Rails 2.1</a> and decided to switch over to the default time zones provided by the Rails. I'm not sure where I picked up the time zone definitions I was using before, but they were things like "US/Central" as opposed to "Central Time (US & Canada)". </p>
<p>Switching to the new time zone definitions provided by Rails means not having to rely on the <a href="http://tzinfo.rubyforge.org">TZInfo</a> gem, because a stripped-down version is now packaged with Rails 2.1. </p>
<p>Here's the migration used to achieve this, which was made with some help from <a href="http://mad.ly/">Geoff Buesing</a> himself:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># db/migrate/20080603023415_use_rails_new_default_time_zones.rb</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> UseRailsNewDefaultTimeZones &lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Migration</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">up</span>
    <span style="color:#0066ff; font-weight:bold;">@users</span> = User.<span style="color:#9900CC;">all</span>
    <span style="color:#0066ff; font-weight:bold;">@users</span>.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> |user|
      user.<span style="color:#9900CC;">time_zone</span> = <span style="color:#996600;">'UTC'</span> <span style="color:#9966CC; font-weight:bold;">if</span> user.<span style="color:#9900CC;">time_zone</span>.<span style="color:#9900CC;">blank</span>?
      tz = <span style="color:#6666ff; font-weight:bold;">TZInfo::Timezone</span>.<span style="color:#9900CC;">get</span><span style="color:#006600; font-weight:bold;">&#40;</span>user.<span style="color:#9900CC;">time_zone</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">rescue</span> <span style="color:#CC00FF; font-weight:bold;">TimeZone</span><span style="color:#006600; font-weight:bold;">&#91;</span>user.<span style="color:#9900CC;">time_zone</span><span style="color:#006600; font-weight:bold;">&#93;</span> || <span style="color:#CC00FF; font-weight:bold;">TimeZone</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'UTC'</span><span style="color:#006600; font-weight:bold;">&#93;</span>
      time_zone = <span style="color:#9966CC; font-weight:bold;">if</span> tz.<span style="color:#9900CC;">is_a</span>?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#6666ff; font-weight:bold;">TZInfo::Timezone</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        linked_timezone = tz.<span style="color:#9900CC;">instance_variable_get</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'@linked_timezone'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
        name = linked_timezone ? linked_timezone.<span style="color:#9900CC;">name</span> : tz.<span style="color:#9900CC;">name</span>
        <span style="color:#6666ff; font-weight:bold;">TimeZone::MAPPING</span>.<span style="color:#9900CC;">index</span><span style="color:#006600; font-weight:bold;">&#40;</span>name<span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">else</span>
        tz.<span style="color:#9900CC;">name</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
      user.<span style="color:#9900CC;">update_attribute</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:time_zone</span>, time_zone<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> time_zone == user.<span style="color:#9900CC;">time_zone</span>
    <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#0066ff; font-weight:bold;">@users</span>.<span style="color:#9900CC;">empty</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">down</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>If you haven't played with <a href="http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/">the new time zone stuff in Rails 2.1</a>, make sure to check it out. It makes dealing with time zones so easy, it's almost unbelievable. Thanks, Geoff!</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/06/03/migrate-to-the-rails-default-time-zones/feed/</wfw:commentRss>
		</item>
		<item>
		<title>El Dorado 0.9.2 (Group Chat Edition)</title>
		<link>http://almosteffortless.com/2008/05/05/el-dorado-092-group-chat-edition/</link>
		<comments>http://almosteffortless.com/2008/05/05/el-dorado-092-group-chat-edition/#comments</comments>
		<pubDate>Tue, 06 May 2008 03:15:18 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[El Dorado]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/?p=676</guid>
		<description><![CDATA[I'm pleased to announce the release of El Dorado version 0.9.2 - the "group chat" edition. You can download it right away, or check out the demo, testing, and support site here:
http://eldorado.almosteffortless.com/
Since we last spoke at the end of January, there's been a goodly amount of activity with El Dorado. The highlight, of course, is [...]]]></description>
			<content:encoded><![CDATA[<p>I'm pleased to announce the release of <a href="http://almosteffortless.com/eldorado/">El Dorado</a> version 0.9.2 - the "group chat" edition. You can <a href="http://github.com/trevorturk/el-dorado/tarball/v0.9.2">download it right away</a>, or check out the demo, testing, and support site here:</p>
<p><a href="http://eldorado.almosteffortless.com/">http://eldorado.almosteffortless.com/</a></p>
<p>Since we <a href="http://almosteffortless.com/2008/01/24/welcome-to-el-dorado/">last spoke</a> at the end of January, there's been a goodly amount of activity with El Dorado. The highlight, of course, is the new group chat feature:</p>
<p><img src="http://almosteffortless.com/files/eldo-chat-2.png" alt="eldo-chat-2" /></p>
<p>This is a very <a href="http://github.com/trevorturk/el-dorado/tree/master/app/controllers/messages_controller.rb">simple</a> and lightweight implementation that's perfect for small groups. It works solely with the tools provided by Rails and doesn't add anything to the overall requirements for running El Dorado. I've been using it with my group of friends for a few weeks now, and it's been working great. I'm sure that I'll have some more features to announce with the next release, but my favorite little touch so far is the "who's in the chat room and when was the chat last active" indicator on the home page: </p>
<p><img src="http://almosteffortless.com/files/eldo-chat-1.png" alt="eldo-chat-1" /></p>
<p>In addition to the addition of group chat, there have been a number of improvements to other parts of the app and quite a bit of back-end optimization/refactoring. Here's a quick list of the new features:</p>
<ul class="bullets">
<li>Make entire site private with a simple admin setting (great for small companies)</li>
<li>View all posts across the entire forum in reverse chronological order</li>
<li>View all posts by individual user</li>
<li>Upload new files quickly and easily via URL</li>
<li>Ability to "sticky" and "lock" forum threads</li>
<li>Move threads to different forums, and forums to different categories</li>
<li>Allow users to stay logged in between different browsers/machines</li>
<li>New calendar interface for setting the date/time of an event</li>
<li>Admin interface for viewing/editing/creating user rankings</li>
<li>Admin interface to grant/revoke admin privileges</li>
<li>Various BBCode additions (Flickr video, Slideshare, FunnyOrDie, etc) and some bug fixes</li>
</ul>
<p>Of course, you can follow along with all of the activity in El Dorado on the <a href="http://github.com/trevorturk/el-dorado/commits/master">commit log</a> at github. You see, being the <a href="http://www.techcrunch.com/2007/08/13/37signals-drives-another-company-to-the-deadpool/">lemming</a> that I am, I've followed Rails to <a href="http://weblog.rubyonrails.org/2008/4/11/rails-premieres-on-github">github</a> and <a href="http://weblog.rubyonrails.org/2008/4/15/rails-and-family-on-lighthouse">Lighthouse</a> already. I haven't had time to settle into Lighthouse just yet, but I've been having a blast with git and github. </p>
<p>In fact, I gave a presentation at <a href="http://chicagoruby.org/articles/2008/03/21/el-dorado-and-esod/">Chicago Ruby</a> and spent a fair amount of time talking about making the move to git. Definitely flip through <a href="http://almosteffortless.com/files/eldo-chicagoruby.pdf">the PDF</a> to learn all about the origin of El Dorado (where the name came from, etc) but take my word for it about one thing: git/github is the way to go: </p>
<p><a href="http://almosteffortless.com/files/eldo-chicagoruby.pdf"><img src="http://almosteffortless.com/files/eldo-chicagoruby.png" alt="eldo-chicagoruby" /></a></p>
<p>If you believe the PDF, then the upcoming of releases should go something like this:</p>
<ul class="bullets">
<li><strike>Chat</strike></li>
<li>Localization (see note below)</li>
<li>Blog</li>
<li>Themes</li>
<li>Photos</li>
<li>Wiki</li>
<li>Polls</li>
<li>Link Sharing</li>
<li>Mobile Messaging</li>
</ul>
<p>Thanks to git/github, <a href="http://github.com/jxl">jxl</a> has been working on a <a href="http://github.com/jxl/el-dorado/tree/master">localized version of El Dorado using Gibberish</a>, and he's already completed a Dutch translation. I'll be working with him to pull his changes into my repo for the next release. If you're interested in translating El Dorado into another language, please do get in touch!</p>
<p>I think that about covers it... so... Welcome to El Dorado v.0.9.2!</p>
<p>Learn more and/or download El Dorado here: <a href="http://almosteffortless.com/eldorado/">http://almosteffortless.com/eldorado/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/05/05/el-dorado-092-group-chat-edition/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Automatically Creating, Loading, and Migrating your Database (with magic!)</title>
		<link>http://almosteffortless.com/2008/04/10/automatically-creating-loading-and-migrating-your-database/</link>
		<comments>http://almosteffortless.com/2008/04/10/automatically-creating-loading-and-migrating-your-database/#comments</comments>
		<pubDate>Fri, 11 Apr 2008 05:31:21 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/?p=674</guid>
		<description><![CDATA[So, let's say you're working on this open source Rails app, and you're doing your best to keep the requirements light and the installation as easy as possible. You'd love to have that Famous 5-Minute Install that WordPress has going for it, and you start to wonder...
Why should I even have to worry about the [...]]]></description>
			<content:encoded><![CDATA[<p>So, let's say you're working on this <a href="/eldorado">open source Rails app</a>, and you're doing your best to keep the requirements light and the installation as easy as possible. You'd <i>love</i> to have that <a href="http://codex.wordpress.org/Installing_WordPress#Famous_5-Minute_Install">Famous 5-Minute Install</a> that WordPress has going for it, and you start to wonder...</p>
<p><i>Why should I even have to worry about the database?</i></p>
<p>Why can't my app take care of itself? Why can't it automatically create and maintain the database for me? </p>
<p>Well friend, I just wrapped up a little initializer that will automatically create the db, load the schema, and/or migrate as necessary. It all seems fine so far, but I still have this funny feeling that I'm doing something wrong...</p>
<pre>&nbsp;
/config/initializers/db_create_load_or_migrate.rb
&nbsp;</pre>
<p>I dunno... Have I gone too far this time?</p>
<pre class="ruby">&nbsp;
<span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#9966CC; font-weight:bold;">defined</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>Rake<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#CC0066; font-weight:bold;">load</span> <span style="color:#996600;">&quot;#{RAILS_ROOT}/Rakefile&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">begin</span>
    current_version = <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Migrator</span>.<span style="color:#9900CC;">current_version</span>
    highest_version = <span style="color:#CC00FF; font-weight:bold;">Dir</span>.<span style="color:#9900CC;">glob</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;#{RAILS_ROOT}/db/migrate/*.rb&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">map</span> <span style="color:#006600; font-weight:bold;">&#123;</span> |f| f.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span>/<span style="color:#006600; font-weight:bold;">&#40;</span>\d+<span style="color:#006600; font-weight:bold;">&#41;</span>_\w*\.<span style="color:#9900CC;">rb</span>$/<span style="color:#006600; font-weight:bold;">&#41;</span> ? $<span style="color:#006666;">1</span>.<span style="color:#9900CC;">to_i</span> : <span style="color:#006666;">0</span> <span style="color:#006600; font-weight:bold;">&#125;</span>.<span style="color:#9900CC;">max</span>
    <span style="color:#6666ff; font-weight:bold;">Rake::Task</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;db:migrate&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">invoke</span> <span style="color:#9966CC; font-weight:bold;">if</span> current_version != highest_version
  <span style="color:#9966CC; font-weight:bold;">rescue</span>
    <span style="color:#6666ff; font-weight:bold;">Rake::Task</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;db:create&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">invoke</span>
    abort <span style="color:#996600;">'ERROR: Database has no schema version and is not empty'</span> <span style="color:#9966CC; font-weight:bold;">unless</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>.<span style="color:#9900CC;">connection</span>.<span style="color:#9900CC;">tables</span>.<span style="color:#9900CC;">blank</span>?
    <span style="color:#6666ff; font-weight:bold;">Rake::Task</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;db:schema:load&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">invoke</span>
    <span style="color:#9966CC; font-weight:bold;">retry</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p><i>Addendum</i></p>
<p>Thanks to the <i>Fail Early</i> chapter of the <a href="http://pragprog.com/titles/fr_arr">Advanced Rails Recipes</a> book for turning me onto the idea of (at least) checking for an up-to-date schema with an initializer. </p>
<p>Also, make sure to check out this nifty trick that lets you run Rake tasks from within a Rails app. It's pretty easy - all you need to do is load the Rails Rakefile and use .invoke:</p>
<pre class="ruby">&nbsp;
<span style="color:#CC0066; font-weight:bold;">load</span> <span style="color:#996600;">&quot;#{RAILS_ROOT}/Rakefile&quot;</span>
<span style="color:#6666ff; font-weight:bold;">Rake::Task</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;db:create&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">invoke</span>
&nbsp;</pre>
<p>P.S. I spent the last hour re-enabling comments on this site, just so somebody like you can tell me that I'm not allowed to do this and why. So, please, have at it!</p>
<p><b>Update</b>: I updated the regex thanks to <a href="http://groups.google.com/group/el-dorado-app/browse_thread/thread/9879757e10b1f7b9">a patch</a> that Ben sent to deal with more kinds of directory names. </p>
<p><b>Update 2</b>: After living with this for a while, I decided to take it out of El Dorado for the time being. I still think it's an interesting idea, but it's too risky to play with production data like this, and I think it's better to be on the safe side. Plus, the Rails developers I've spoken to about it seem to think that it's introducing unexpected behavior into the app (e.g. auto-migrations are not the norm).</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/04/10/automatically-creating-loading-and-migrating-your-database/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Sharing Code Between ActiveRecord Models</title>
		<link>http://almosteffortless.com/2008/01/29/sharing-code-between-activerecord-models/</link>
		<comments>http://almosteffortless.com/2008/01/29/sharing-code-between-activerecord-models/#comments</comments>
		<pubDate>Wed, 30 Jan 2008 05:10:39 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/2008/01/29/sharing-code-between-activerecord-models/</guid>
		<description><![CDATA[I was frustrated with the amount of duplicated code sprinkled in my models that are using the attachment_fu plugin to deal with file uploads. It's not like I need to write a plugin or anything fancy - I just want to be a little more DRY. 
So, how does one simply share code between ActiveRecord [...]]]></description>
			<content:encoded><![CDATA[<p>I was frustrated with the amount of duplicated code sprinkled in my models that are using the <a href="http://almosteffortless.com/2007/03/25/working-with-attachment_fu/">attachment_fu</a> plugin to deal with file uploads. It's not like I need to write a plugin or anything fancy - I just want to be a little more <a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">DRY</a>. </p>
<p>So, how does one simply share code between <a href="http://api.rubyonrails.org/classes/ActiveRecord/Base.html">ActiveRecord</a> models? It's actually quite easy.</p>
<p>First, drop some code into a module in a .rb file in your lib directory. For example:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># lib/attachment_fu_extensions.rb</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> AttachmentFuExtensions
&nbsp;
  <span style="color:#008000; font-style:italic;"># include some standard attachment_fu stuff</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">included</span><span style="color:#006600; font-weight:bold;">&#40;</span>klass<span style="color:#006600; font-weight:bold;">&#41;</span>
    klass.<span style="color:#9900CC;">send</span> <span style="color:#ff3333; font-weight:bold;">:validates_as_attachment</span>
    klass.<span style="color:#9900CC;">send</span> <span style="color:#ff3333; font-weight:bold;">:validates_uniqueness_of</span>, <span style="color:#ff3333; font-weight:bold;">:filename</span>
    klass.<span style="color:#9900CC;">send</span> <span style="color:#ff3333; font-weight:bold;">:validates_presence_of</span>, <span style="color:#ff3333; font-weight:bold;">:user_id</span>
    klass.<span style="color:#9900CC;">send</span> <span style="color:#ff3333; font-weight:bold;">:attr_protected</span>, <span style="color:#ff3333; font-weight:bold;">:id</span>, <span style="color:#ff3333; font-weight:bold;">:parent_id</span>, <span style="color:#ff3333; font-weight:bold;">:user_id</span>, <span style="color:#ff3333; font-weight:bold;">:created_at</span>, <span style="color:#ff3333; font-weight:bold;">:updated_at</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># upload into a single directory (e.g. public/uploads) instead of subdirectories based on the id</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> full_filename<span style="color:#006600; font-weight:bold;">&#40;</span>thumbnail = <span style="color:#0000FF; font-weight:bold;">nil</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    file_system_path = <span style="color:#006600; font-weight:bold;">&#40;</span>thumbnail ? thumbnail_class : <span style="color:#0000FF; font-weight:bold;">self</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">attachment_options</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:path_prefix</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_s</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, file_system_path, thumbnail_name_for<span style="color:#006600; font-weight:bold;">&#40;</span>thumbnail<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>
&nbsp;
  <span style="color:#008000; font-style:italic;"># prevent users from uploading index files that would be served instead of the index template/action</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> validate
    errors.<span style="color:#9900CC;">add</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;filename&quot;</span>, <span style="color:#996600;">&quot;is invalid&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> filename? &amp;&amp; %w<span style="color:#006600; font-weight:bold;">&#40;</span>index.<span style="color:#9900CC;">html</span> index.<span style="color:#9900CC;">htm</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9966CC; font-weight:bold;">include</span>?<span style="color:#006600; font-weight:bold;">&#40;</span>filename.<span style="color:#9900CC;">downcase</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>
&nbsp;</pre>
<p>That code will automatically be loaded when your application starts, provided that the filename and module follow the standard Rails <a href="http://giantrobots.thoughtbot.com/2007/8/8/auto-load">naming conventions</a>. </p>
<p>Then, simply include the relevant module in the relevant models. For example:</p>
<pre class="ruby">&nbsp;
<span style="color:#008000; font-style:italic;"># app/models/upload.rb</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> Upload &lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  has_attachment <span style="color:#ff3333; font-weight:bold;">:storage</span> =&gt; <span style="color:#ff3333; font-weight:bold;">:file_system</span>, <span style="color:#ff3333; font-weight:bold;">:path_prefix</span> =&gt; <span style="color:#996600;">'public/uploads'</span>, <span style="color:#ff3333; font-weight:bold;">:max_size</span> =&gt; <span style="color:#006666;">10</span>.<span style="color:#9900CC;">megabytes</span>
  <span style="color:#9966CC; font-weight:bold;">include</span> AttachmentFuExtensions
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>That's it. Extending ActiveRecord models and DRYing out your app is pretty easy, eh? </p>
<p><b>Update:</b> <a href="http://kete.net.nz/">Walter</a> pointed out that I should put modules like this into lib/ instead of config/initializers/, so I've updated this post to reflect that. I'm not sure why that didn't occur to me. He also told me about the trick for sharing calls to validates_as_attachment and so forth - I didn't even know that was possible!</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/01/29/sharing-code-between-activerecord-models/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Welcome to El Dorado!</title>
		<link>http://almosteffortless.com/2008/01/24/welcome-to-el-dorado/</link>
		<comments>http://almosteffortless.com/2008/01/24/welcome-to-el-dorado/#comments</comments>
		<pubDate>Fri, 25 Jan 2008 04:26:31 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[El Dorado]]></category>

		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/2008/01/24/welcome-to-el-dorado/</guid>
		<description><![CDATA[
I'm pleased to announce the first public release of El Dorado: a full-stack community web application written in Ruby/Rails. This is a stable beta version of the app, which is being released in anticipation of the 1.0 release scheduled for this spring. 
The app features a forum, community event calendar, shared file storage, and a [...]]]></description>
			<content:encoded><![CDATA[<p style="float:right;margin-top:0;"><a href="/eldorado/"><img src="http://almosteffortless.com/files/el-d-200.jpg" alt="eldorado" /></a></p>
<p>I'm pleased to announce the first public release of <a href="/eldorado/">El Dorado</a>: a full-stack community web application written in Ruby/Rails. This is a stable beta version of the app, which is being released in anticipation of the 1.0 release scheduled for this spring. </p>
<p>The app features a forum, community event calendar, shared file storage, and a randomized header image gallery. The forum is somewhat modeled on <a href="http://punbb.org">PunBB</a> (one of the more popular PHP forums) and can import from an existing site using PunBB. </p>
<p>The app has been used in production since late July '07. The setup/administration process still leave something to be desired, but the end-user functionality is quite well tested.</p>
<p><a href="/files/eldo-home.png" rel=â€lightboxâ€><img src="/files/eldo-home.png" alt="Home" style="width:100px;margin:0px 22px;" /></a><a href="/files/eldo-forum.png" rel=â€lightboxâ€><img src="/files/eldo-forum.png" alt="Forum" style="width:100px;margin:0px 22px;" /></a><a href="/files/eldo-topics.png" rel=â€lightboxâ€><img src="/files/eldo-topics.png" alt="Topics" style="width:100px;margin:0px 22px;" /></a><a href="/files/eldo-files.png" rel=â€lightboxâ€><img src="/files/eldo-files.png" alt="Files" style="width:100px;margin:0px 22px;" /></a><a href="/files/eldo-events.png" rel=â€lightboxâ€><img src="/files/eldo-events.png" alt="Events" style="width:100px;margin:0px 22px;" /></a></p>
<p>You can get the download or more information on the <a href="http://almosteffortless.com/eldorado/">El Dorado homepage</a>, or check out the demo, testing, and support site here: <a href="http://eldorado.almosteffortless.com">eldorado.almosteffortless.com</a>. Also, consider subscribing to the <a href="http://feeds.feedburner.com/almosteffortless">almost effortless RSS feed</a> to stay informed about upcoming releases and the occasional Ruby/Rails-related post. </p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/01/24/welcome-to-el-dorado/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Simplifying and sharing code with Rails conventions</title>
		<link>http://almosteffortless.com/2008/01/07/simplifying-and-sharing-code-with-rails-conventions/</link>
		<comments>http://almosteffortless.com/2008/01/07/simplifying-and-sharing-code-with-rails-conventions/#comments</comments>
		<pubDate>Tue, 08 Jan 2008 05:06:03 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/2008/01/07/simplifying-and-sharing-code-by-using-rails-conventions/</guid>
		<description><![CDATA[One of the benefits of convention over configuration in Rails is that you can make assumptions about a lot of stuff. A good example of this is the user_id column found in most Rails database tables. 
If you see a user_id column in a schema, you can typically infer that it represents the unique identifier [...]]]></description>
			<content:encoded><![CDATA[<p>One of the benefits of <a href="http://en.wikipedia.org/wiki/Convention_over_Configuration">convention over configuration</a> in Rails is that you can make assumptions about a lot of stuff. A good example of this is the <i>user_id</i> column found in most Rails database tables. </p>
<p>If you see a <i>user_id</i> column in a schema, you can typically infer that it represents the unique identifier (<i>id</i>) of the user that created that record. This leads to all kinds of interesting opportunities for code simplification.</p>
<p>I'll take you through a basic example found in my open-source app, <a href="http://almosteffortless.com/eldorado">El Dorado</a> to demonstrate. This example will show you how to share code related to authentication throughout your app. We'll start by looking at the <b>user</b>, <b>topic</b>, and <b>post</b> database objects defined in <a href="http://eldorado.googlecode.com/svn/trunk/db/schema.rb">schema.rb</a>:</p>
<pre class="ruby">&nbsp;
create_table <span style="color:#996600;">&quot;users&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> =&gt; <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> |t|
  t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;login&quot;</span>
  t.<span style="color:#9900CC;">boolean</span>  <span style="color:#996600;">&quot;admin&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:default</span> =&gt; <span style="color:#0000FF; font-weight:bold;">false</span>
  <span style="color:#008000; font-style:italic;"># ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
create_table <span style="color:#996600;">&quot;topics&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> =&gt; <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> |t|
  t.<span style="color:#CC0066; font-weight:bold;">integer</span>  <span style="color:#996600;">&quot;user_id&quot;</span>
  t.<span style="color:#CC0066; font-weight:bold;">string</span>   <span style="color:#996600;">&quot;title&quot;</span>
  <span style="color:#008000; font-style:italic;"># ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
create_table <span style="color:#996600;">&quot;posts&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:force</span> =&gt; <span style="color:#0000FF; font-weight:bold;">true</span> <span style="color:#9966CC; font-weight:bold;">do</span> |t|
  t.<span style="color:#CC0066; font-weight:bold;">integer</span>  <span style="color:#996600;">&quot;user_id&quot;</span>
  t.<span style="color:#9900CC;">text</span>     <span style="color:#996600;">&quot;body&quot;</span>
  <span style="color:#008000; font-style:italic;"># ...</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>According to Rails conventions, the <i>user_id</i> field in the topics and posts tables should reference the <i>id</i> field in the users table. (The id field is assumed and not mentioned in the schema.rb file.) This convention is what allows you to do things like:</p>
<pre class="ruby">&nbsp;
<span style="color:#0066ff; font-weight:bold;">@user</span> = User.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#0066ff; font-weight:bold;">@user</span>.<span style="color:#9900CC;">topics</span> <span style="color:#008000; font-style:italic;"># the topics the user has created</span>
<span style="color:#0066ff; font-weight:bold;">@user</span>.<span style="color:#9900CC;">posts</span> <span style="color:#008000; font-style:italic;"># the posts the user has created</span>
&nbsp;</pre>
<p>This also lets you share code amongst all of the controllers and views in an application. Let's use a basic concept for authentication: checking for permission to edit an item. Using some of the conventions introduced in the <a href="http://svn.techno-weenie.net/projects/plugins/restful_authentication/">restful_authentication</a> plugin, we'll be able to add some basic permission checking that will work for any model that has a <i>user_id</i> field, and for users that have an <i>id</i> field. We'll assume that a user has permission to edit an item if (a) they're an administrator, or (b) they've created the item they're trying to edit. </p>
<p>We'll start by adding the following to <a href="http://eldorado.googlecode.com/svn/trunk/app/controllers/application.rb">application.rb</a>:</p>
<pre class="ruby">&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController &lt; <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
&nbsp;
  helper_method <span style="color:#ff3333; font-weight:bold;">:current_user</span>, <span style="color:#ff3333; font-weight:bold;">:logged_in</span>?, <span style="color:#ff3333; font-weight:bold;">:admin</span>?, <span style="color:#ff3333; font-weight:bold;">:can_edit</span>?
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> current_user
    <span style="color:#0066ff; font-weight:bold;">@current_user</span> ||= <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#40;</span>session<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user_id</span><span style="color:#006600; font-weight:bold;">&#93;</span> &amp;&amp; User.<span style="color:#9900CC;">find_by_id</span><span style="color:#006600; font-weight:bold;">&#40;</span>session<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:user_id</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span> || <span style="color:#006666;">0</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;">def</span> logged_in?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    current_user != <span style="color:#006666;">0</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> admin?<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    logged_in? &amp;&amp; <span style="color:#006600; font-weight:bold;">&#40;</span>current_user.<span style="color:#9900CC;">admin</span> == <span style="color:#0000FF; font-weight:bold;">true</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;">def</span> can_edit?<span style="color:#006600; font-weight:bold;">&#40;</span>current_item<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;">false</span> <span style="color:#9966CC; font-weight:bold;">unless</span> logged_in?
    <span style="color:#9966CC; font-weight:bold;">if</span> request.<span style="color:#9900CC;">path_parameters</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'controller'</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">&quot;users&quot;</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> current_user.<span style="color:#9900CC;">admin</span>? || <span style="color:#006600; font-weight:bold;">&#40;</span>current_user == current_item<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      <span style="color:#0000FF; font-weight:bold;">return</span> current_user.<span style="color:#9900CC;">admin</span>? || <span style="color:#006600; font-weight:bold;">&#40;</span>current_user.<span style="color:#9900CC;">id</span> == current_item.<span style="color:#9900CC;">user_id</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>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> can_edit
    redirect_to root_path <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">unless</span> logged_in?
    klass = request.<span style="color:#9900CC;">path_parameters</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'controller'</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">singularize</span>.<span style="color:#9900CC;">classify</span>.<span style="color:#9900CC;">constantize</span>
    <span style="color:#0066ff; font-weight:bold;">@item</span> = klass.<span style="color:#9900CC;">find</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;">:id</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> request.<span style="color:#9900CC;">path_parameters</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'controller'</span><span style="color:#006600; font-weight:bold;">&#93;</span> == <span style="color:#996600;">&quot;users&quot;</span>
      redirect_to root_path <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">unless</span> admin? || <span style="color:#006600; font-weight:bold;">&#40;</span>current_user == <span style="color:#0066ff; font-weight:bold;">@item</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">else</span>
      redirect_to root_path <span style="color:#9966CC; font-weight:bold;">and</span> <span style="color:#0000FF; font-weight:bold;">return</span> <span style="color:#0000FF; font-weight:bold;">false</span> <span style="color:#9966CC; font-weight:bold;">unless</span> admin? || <span style="color:#006600; font-weight:bold;">&#40;</span>current_user == <span style="color:#0066ff; font-weight:bold;">@item</span>.<span style="color:#9900CC;">user</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>
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>The <i>current_user</i> bit assumes that you're setting the <i>session[:user_id]</i> value to the currently logged-in user's <i>id</i>. (If you're unsure how to accomplish this and/or aren't doing it already, you should give the <a href="http://svn.techno-weenie.net/projects/plugins/restful_authentication/">restful_authentication</a> plugin a gander.) The <i>logged_in?</i> helper will return true if the user is logged in, and the <i>admin?</i> helper will return true if the logged-in user has their <i>admin</i> attribute set to true. </p>
<p>The <i>can_edit?</i> helper and the <i>can_edit</i> action are where the real action is. We'll start with the <i>can_edit</i> action, which allows you to do the following in any controller in your application:</p>
<pre class="ruby">&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> TopicsController &lt; ApplicationController
&nbsp;
  before_filter <span style="color:#ff3333; font-weight:bold;">:can_edit</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> =&gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:edit</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> PostsController &lt; ApplicationController 
&nbsp;
  before_filter <span style="color:#ff3333; font-weight:bold;">:can_edit</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> =&gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:edit</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">class</span> UsersController &lt; ApplicationController
&nbsp;
  before_filter <span style="color:#ff3333; font-weight:bold;">:can_edit</span>, <span style="color:#ff3333; font-weight:bold;">:only</span> =&gt; <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:edit</span>, <span style="color:#ff3333; font-weight:bold;">:update</span>, <span style="color:#ff3333; font-weight:bold;">:destroy</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;</pre>
<p>The <i>can_edit</i> action is accessible to any controller, and it can be used to check the editing permissions for any item without any additional code overhead. If the user is logged in and is an administrator, they'll be allowed to proceed. Otherwise, the action will check to see if the user is trying to edit an item that they created, or their own user account. If so, they'll be allowed to proceed; if not, they'll be redirected to the root_path. This, of course, requires the defining of a <i>root_path</i> in your <a href="http://eldorado.googlecode.com/svn/trunk/config/routes.rb">routes.rb</a> file:</p>
<pre class="ruby">&nbsp;
map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> =&gt; <span style="color:#996600;">'home'</span>
&nbsp;</pre>
<p>That's pretty nice, and there's also the <i>can_edit?</i> helper that can also be shared across all views. Here's a couple of examples. The first would be useful in, say, the <i>user/show</i> view. The second, perhaps in <i>posts/show</i>...?</p>
<pre class="ruby">&nbsp;
&lt;%= link_to <span style="color:#996600;">'Edit User'</span>, edit_user_path<span style="color:#006600; font-weight:bold;">&#40;</span>@user<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> can_edit?<span style="color:#006600; font-weight:bold;">&#40;</span>@user<span style="color:#006600; font-weight:bold;">&#41;</span> %&gt;
&lt;%= link_to <span style="color:#996600;">'Edit Post'</span>, edit_post_path<span style="color:#006600; font-weight:bold;">&#40;</span>@post<span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">if</span> can_edit?<span style="color:#006600; font-weight:bold;">&#40;</span>@post<span style="color:#006600; font-weight:bold;">&#41;</span> %&gt;
&nbsp;</pre>
<p>And there you have a great example of the benefits of convention in Rails app. You can do a lot of cool stuff with very little code. Plus, <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> code is always nice. Of course, you can dig further into the whole kit and kaboodle behind this by checking out the <a href="http://almosteffortless.com/eldorado/">El Dorado</a> source...</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2008/01/07/simplifying-and-sharing-code-with-rails-conventions/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Configuring Cookie-Based Sessions in Rails 2.0</title>
		<link>http://almosteffortless.com/2007/12/27/configuring-cookie-based-sessions-in-rails-20/</link>
		<comments>http://almosteffortless.com/2007/12/27/configuring-cookie-based-sessions-in-rails-20/#comments</comments>
		<pubDate>Fri, 28 Dec 2007 03:48:40 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/2007/12/27/configuring-cookie-based-sessions-in-rails-20/</guid>
		<description><![CDATA[As of Changeset 6184 and the release of Rails 2.0, the default session store for Rails apps is cookie-based. 
[This] means sessions are no longer stored on the file system or in the database, but kept by the client in a hashed form that canâ€™t be forged. This makes it not only a lot faster [...]]]></description>
			<content:encoded><![CDATA[<p>As of <a href="http://dev.rubyonrails.org/changeset/6184">Changeset 6184</a> and the <a href="http://weblog.rubyonrails.org/2007/12/7/rails-2-0-it-s-done">release of Rails 2.0</a>, the default session store for Rails apps is cookie-based. </p>
<blockquote><p>[This] means sessions are no longer stored on the file system or in the database, but kept by the client in a hashed form that canâ€™t be forged. This makes it not only a lot faster than traditional session stores, but also makes it zero maintenance. Thereâ€™s no cron job needed to clear out the sessions and your server wonâ€™t crash because you forgot and suddenly had 500K files in tmp/session.</p></blockquote>
<p><a href="http://ryandaigle.com/articles/2007/2/21/what-s-new-in-edge-rails-cookie-based-sessions">Configuring your application</a> to use this speedy new session store is easy. Adding the following to your config/environment.rb file <i>would</i> do the trick:</p>
<pre>
config.action_controller.session = {
  :session_key => '_my_app_session',
  :secret      => 'some_really_long_and_hashed_key'
}
</pre>
<p><b>But...</b></p>
<p>I don't like it. </p>
<p>Especially when you're dealing with open-source projects, putting what amounts to installation-specific passwords here doesn't seem appropriate. In the case of my open-source project, <a href="http://almosteffortless.com/eldorado">El Dorado</a>, I'd like to be able to make changes to environment.rb without troubling the user. Ideally, I think all passwords should be set from a single location. Luckily, it's easy to push this configuration into the already available config/database.yml. </p>
<p>Here's how.</p>
<p>Add the following to config/environment.rb:</p>
<pre>
require 'yaml'
db = YAML.load_file('config/database.yml')
config.action_controller.session = {
  :session_key => db[RAILS_ENV]['session_key'],
  :secret      => db[RAILS_ENV]['secret']
}
</pre>
<p>And then you can set everything up in one place: config/database.yml:</p>
<pre>
development:
  adapter: mysql
  database: eldorado_development
  username: root
  password:
  host: localhost
  session_key: eldorado_development
  secret: YrDOFOmYJyFg2tTZykCbZjWYQUbKBt

test:
  adapter: mysql
  database: eldorado_test
  username: root
  password:
  host: localhost
  session_key: eldorado_test
  secret: Pl8qJNFc8mo1yt1xtHOmfUGHOPEutu

production:
  adapter: mysql
  database: eldorado_production
  username: root
  password:
  host: localhost
  session_key: eldorado_production
  secret:
</pre>
<p>This seems more... natural. Don't you think? </p>
<p>Anyway, <a href="http://railscasts.com/episodes/85">using YAML files</a> for app configuration is the way of the future.</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2007/12/27/configuring-cookie-based-sessions-in-rails-20/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Random Records in Rails</title>
		<link>http://almosteffortless.com/2007/12/04/random-records-in-rails/</link>
		<comments>http://almosteffortless.com/2007/12/04/random-records-in-rails/#comments</comments>
		<pubDate>Wed, 05 Dec 2007 01:20:16 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://almosteffortless.com/2007/12/04/random-records-in-rails/</guid>
		<description><![CDATA[There are a number of different ways to retrieve random items from a database in Rails, most of which have been discussed at length on the Rails wiki. According to this article, there are 3 preferred methods:


1. Select a Record by Random Offset
2. Randomize with the Database
3. Randomize with Ruby


For an in-depth look into these [...]]]></description>
			<content:encoded><![CDATA[<p>There are a number of different ways to retrieve random items from a database in Rails, most of which have been discussed at length on the Rails wiki. According to <a href="http://wiki.rubyonrails.org/rails/pages/HowtoSelectRandomRecords">this article</a>, there are 3 preferred methods:</p>
<blockquote>
<ol>
<li>1. Select a Record by Random Offset</li>
<li>2. Randomize with the Database</li>
<li>3. Randomize with Ruby</li>
</ol>
</blockquote>
<p>For an in-depth look into these options, you can peruse <a href="http://wiki.rubyonrails.org/rails/pages/RandomAccessRecordsDiscussion">this discussion page</a>, which details some of the pros and cons of different strategies for randomization.</p>
<p>After trying out a few of the techniques that abound in this area, I stumbled across <a href="http://weblog.jamisbuck.org/2006/10/7/helping-activerecord-finders-help-you">an article from Jamis Buck</a>, where he discusses a <a href="http://ryandaigle.com/articles/2006/08/01/whats-new-in-edge-rails-simply-restful-support-and-how-to-use-it">RESTful</a> way to approach the creation of custom finders. Although randomization isn't the focus of the article, he does provide a bit of guidance in that regard. His strategy uses Ruby for the randomization, and employs 2 light-weight queries. The first query gathers a list of valid ids. The second simply selects a single item using that (randomized) id.</p>
<p>So, I did a bit of <a href="http://weblog.jamisbuck.org/2008/1/7/never-ever-cargo-cult">cargo-culting</a> and repurposing to achieve an efficient, database agnostic way to retrieve random items from a database using <a href="http://api.rubyonrails.com/classes/ActiveRecord/Base.html">ActiveRecord</a>. Simply add the following to the model from which you'd like to be able to pull random records:</p>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> Widget &lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">random</span>
    ids = connection.<span style="color:#9900CC;">select_all</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;SELECT id FROM widgets&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    find<span style="color:#006600; font-weight:bold;">&#40;</span>ids<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#CC0066; font-weight:bold;">rand</span><span style="color:#006600; font-weight:bold;">&#40;</span>ids.<span style="color:#9900CC;">length</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;id&quot;</span><span style="color:#006600; font-weight:bold;">&#93;</span>.<span style="color:#9900CC;">to_i</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">unless</span> ids.<span style="color:#9900CC;">blank</span>?
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
<p>Then, you can use the following bit of code in a controller like so:</p>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> SomeController &lt; ApplicationController
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> some_action
    <span style="color:#0066ff; font-weight:bold;">@widget</span> = Widget.<span style="color:#9900CC;">random</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
<p>And you've got a small and efficient "random finder" for use throughout your app. Lovely.</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2007/12/04/random-records-in-rails/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Graceful 404s in Rails 2.0</title>
		<link>http://almosteffortless.com/2007/10/08/graceful-404s-in-rails-20/</link>
		<comments>http://almosteffortless.com/2007/10/08/graceful-404s-in-rails-20/#comments</comments>
		<pubDate>Tue, 09 Oct 2007 04:45:13 +0000</pubDate>
		<dc:creator>Trevor</dc:creator>
		
		<category><![CDATA[Rails]]></category>

		<guid isPermaLink="false">http://www.almosteffortless.com/2007/10/08/graceful-404s-in-rails-20/</guid>
		<description><![CDATA[With the upcoming Rails 2.0: Preview Release starting to get some attention, I thought I'd take a moment to play with some of the new features. One of my favorite additions is the new exception handling stuff. It works just like a before_filter, so you'll pick it up straight away.
Action Pack: Exception handling:
Lots of common [...]]]></description>
			<content:encoded><![CDATA[<p>With the upcoming <a href="http://weblog.rubyonrails.org/2007/9/30/rails-2-0-0-preview-release">Rails 2.0: Preview Release</a> starting to get some attention, I thought I'd take a moment to play with some of the new features. One of my favorite additions is the new exception handling stuff. It works just like a before_filter, so you'll pick it up straight away.</p>
<blockquote><p><b>Action Pack: Exception handling:</b></p>
<p>Lots of common exceptions would do better to be rescued at a shared level rather than per action. This has always been possible by overwriting rescue_action_in_public, but then you had to roll out your own case statement and call super. Bah. So now we have a class level macro called rescue_from, which you can use to declaratively point certain exceptions to a given action.</p></blockquote>
<p>The following is quick example you can use to catch 404 Record Not Found errors. It will catch all 404s on your site and display a nice message, instead of an ugly white page of death:</p>
<p><img src="?file_id=file-not-found-1.jpeg" alt="file-not-found-1.jpeg" /></p>
<p>Simply dip into the ApplicationController and add the following code:</p>
<pre class="ruby"><span style="color:#9966CC; font-weight:bold;">class</span> ApplicationController &lt; <span style="color:#6666ff; font-weight:bold;">ActionController::Base</span>
&nbsp;
  rescue_from <span style="color:#6666ff; font-weight:bold;">ActiveRecord::RecordNotFound</span>, <span style="color:#ff3333; font-weight:bold;">:with</span> =&gt; <span style="color:#ff3333; font-weight:bold;">:record_not_found</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> record_not_found
    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> = <span style="color:#996600;">&quot;Sorry, the page you requested was not found.&quot;</span>
    redirect_to root_path
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># ...</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre>
<p>...to display a nice message within your app:</p>
<p><img src="?file_id=file-not-found-2.jpeg" alt="file-not-found-2.jpeg" /></p>
<p>...and there you have it: Easy as Pie(tm) Record Not Found exception handling.</p>
<p><i>P.S.</i></p>
<p>This also takes advantage of my favorite <i>tiny</i> addition to Rails, <a href="http://dev.rubyonrails.org/changeset/5671">map.root</a>. I didn't see this mentioned in the release announcement, but it's covered in the video of the <a href="http://railsconfeurope.railsonwave.com/video">Railsconf Europe '07</a> video. </p>
<p>Instead of this:</p>
<pre class="ruby">map.<span style="color:#9900CC;">home</span> <span style="color:#996600;">''</span>, <span style="color:#ff3333; font-weight:bold;">:controller</span> =&gt; <span style="color:#996600;">'home'</span></pre>
<p>...you can now do this:</p>
<pre class="ruby">map.<span style="color:#9900CC;">root</span> <span style="color:#ff3333; font-weight:bold;">:controller</span> =&gt; <span style="color:#996600;">'home'</span></pre>
<p>It's not a big change, but it's just... <i>nice</i>, isn't it?</p>
]]></content:encoded>
			<wfw:commentRss>http://almosteffortless.com/2007/10/08/graceful-404s-in-rails-20/feed/</wfw:commentRss>
		</item>
	<feedburner:awareness xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">http://api.feedburner.com/awareness/1.0/GetFeedData?uri=almosteffortless</feedburner:awareness></channel>
</rss>
