Things I commonly do when starting a Rails project

Here’s another post from me for me. When starting a new Ruby on Rails project, I tend to do several things the same each time.

1. Setup SVN repository. Most of my projects are completely unrelated, so I usually have to setup a separate repository. The best walkthrough I’ve found is here.

2. Create development/test databases in mysql:

create database project_development;
create database project_test;

3. Setup ActiveRecord sessions:

rake db:sessions:create
rake db:migrate

(uncomment line in config/environment.rb)

config.action_controller.session_store = :active_record_store

4. Setup initial controller…something like:

script/generate controller Main index

And make it the default route (edit the file config/routes.rb)

# Install the default route as the lowest priority.
map.connect ':controller/:action/:id', :controller => 'main'

(Don’t forget to delete or rename public/index.html)

5. I almost always need user accounts. The ActsAsAuthenticated plugin works well:

script/plugin install http://svn.techno-weenie.net/projects/plugins/acts_as_authenticated
script/generate authenticated user account
rake db:migrate

Look in the newly created app/controller/account_controller.rb for a few things to move to app/controller/application.rb

6. While editing app/controller/application.rb, here are a bunch of date/time formatting shortcuts I use a lot:
ActiveSupport::CoreExtensions::Time::Conversions::DATE_FORMATS.merge!(
:date_time12 => "%m/%d/%Y %I:%M%p",
:regular => "%b %d %I:%M %p",
:date_time24 => "%m/%d/%Y %H:%M",
:pretty_date => "%B %d, %Y",
:month_year => "%B %Y",
:short_month_year => "%b %Y",
:month_day => "%b %d",
:pretty_date_time => "%B %d, %Y %I:%M %p",
:short_date => "%b %d, %Y",
:short_12 => "%b %d %I:%M %p",
:standard => "%m/%d/%Y"
)
ActiveSupport::CoreExtensions::Date::Conversions::DATE_FORMATS.merge!(
:pretty_date => "%B %d, %Y",
:month_year => "%B %Y",
:short_month_year => "%b %Y",
:year_only => "%Y",
:month_day => "%b %d",
:short_date => "%b %d, %Y",
:standard => "%m/%d/%Y"
)

Just add all of that to the bottom of application.rb, then use like this: object.created_at.to_s(:standard)

7. Other essential plugins include:

CalendarDateSelect

script/plugin install http://calendardateselect.googlecode.com/svn/tags/calendar_date_select

FileColumn

script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk
mv vendor/plugins/trunk vendor/plugins/filecolumn

ValidatesEmailVeracityOf

script/plugin install http://svn.savvica.com/public/plugins/validates_email_veracity_of

DynamicSessionExp

script/plugin install http://svn.codahale.com/dynamic_session_exp/trunk
mv vendor/plugins/trunk vendor/plugins/dynamic_session_exp

8. Create a default layout for all controllers: app/views/layouts/application.rhtml (If you have a controller needing its own layout, just create one called, “controller.rhtml”) Here is a basic application.rhtml:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title><%= @page_title || 'Site Name' %></title>
<%= stylesheet_link_tag 'all', :media=>'all' %>
<%= stylesheet_link_tag 'print', :media=>'print' %>
<%= javascript_include_tag :defaults %>
<%= calendar_date_select_includes %>
<!--[if lt IE 7]>
<script defer src="/javascripts/pngfix.js" type="text/javascript"></script>
<![endif]-->
</head>
<body>
<% if flash[:notice] -%>
<div class="flash_notice" id="Flash"><%= flash[:notice] %></div>
<% end -%>
<% if flash[:alert] -%>
<div class="flash_alert" id="Flash"><%= flash[:alert] %></div>
<% end -%>
<%= yield %>
</body>
</html>

9. Default public stuff (pngfix.js, latest scriptaculous, stylesheets, images, etc.)

Advertisements

Asher and the iPod Nano

After leaving Applebees Asher tells me, “My meal came with a toy.”

Applebees isn’t the fanciest place around, but they don’t reduce themselves to  fast-food trickery by bribing children with worthless plastic toys. “Oh, really? What is it?”

“An iPod Nano,” he responds.

“Wow, that sounds like a pretty good deal. I don’t know of many kindergarteners with an iPod.”

“Yep. It is right here in my pocket,” he tells me…tapping his front pocket on his pants.

“Let me see that…” I can tell there is something in his pocket, so I try to retrieve the item.

“I’ll show you!”

Sure enough, Asher produces a silver iPod Nano from his pocket. He connects the earbuds to his ears and begins selecting his playlist.

“Wait a minute. Where did you get that?”

With a crooked grin and one eyebrow raised he tries to convince me, “It was part of my meal at Applebees.”

“I already know that is your mom’s iPod.”

Asher giggles.

It turns out, he had it in his pocket all day. I’m not a big fan of the thing since Apple’s latest firmware chokes when used with Linux, but it must be pretty indestructible if it can survive a day in Asher’s pants.

Asher and the Easter Egg

Working on the annual Christmas newsletter I remembered a story about Asher. I figured I’d better record it before I forget.

In the afternoon on Easter, Tina had gone to visit her grandparents. I stayed home with the kids because they were all just a little sick. I was busy cooking dinner when Asher approached me in the kitchen.

Motioning toward the paper towels, “Can I have one of those that is a little bit wet?” he asked.

“Why do you need one?”

“Because this is leaking,” he responded, holding a plastic Easter egg in his right hand.

“What is it leaking?” I asked.

I assumed he had filled it with water from the bathroom sink or something similar.

“Pee,” he responded, as if I should have known that already.

“PEE!?!? How did it get pee in it?”

“I peed in it.” (I guess I should have known the answer to that one.)

“Asher, why would you do that?”

Sensing he was about to get into trouble he responded, “Well, I told the truth.”

Then we began our second treasure hunt of the day. This time, we had to find all of the places on the floor where pee had leaked out of the egg. Asher ended up not getting into trouble. I think I forgot after laughing about the whole thing.

What are we going to do with this kid?

Writer Strike

I can’t believe we’ve survived this long without new TV shows. All this time I thought TV and movies were essential to life. Turns out, nobody has died from a lack of TV watching.

Hostmonster on Rails

A client of mine recently moved their web hosting to Hostmonster, and I was tasked with migrating a Ruby on Rails application to the new server. I ran into a few snags.

First of all, I followed their tutorial.

The default rails welcome page worked fine, but I kept getting “Application Error” on everything else. The logs showed nothing. I found several message board posts pointing to the permissions on the “public” folder.  Dr. Chuck had the best article on the subject.

Dr. Chuck’s instructions fixed the problem for a month or two.  Then it stopped working again. I figured some server-side process had changed the permissions on my files. So, I set it up again. It still didn’t work.

I actually had to contact tech support. A couple of days later they responded with the solution (thankfully, this isn’t a mission-critical app). Hostmonster had recently updated to a newer version of Rails. So, I just commented out the version in the rails environment file:

#config/environment.rb
#...
#RAILS_GEM_VERSION = '1.2.5' unless defined? RAILS_GEM_VERSION

I believe that tells the application to use whatever version of rails it can find (the most recent version on the server). Since version 1.2.5 had apparently been replaced with 1.2.6, removing the declaration for 1.2.5 fixed the problem.

The part that still confuses me is, I had tried generating the application from scratch while logged into the Hostmonster server (via ssh). Doing so still generated an environment.rb file for version 1.2.5.

Of course, the other part that confuses me is why did 1.2.5 stop working?  When I update my own servers with ‘gem update’, I keep old versions available for backwards compatibility of existing rails apps. As far as I know, there is no problem doing it this way. Am I wrong?