Posts Tagged rails 3 upgrade

Setting up Rails 3 on Rackspace Cloud Servers

QUICK UPDATE 03-14-2011 – PLEASE READ – This tutorial was written when Rails 3 was in beta. Some of this info may be outdated. This tutorial will be updated soon, but here are a few notes until I get to it:  For steps 6 & 7, use RVM and install 1.9.2 using RVM. This should install rubygems, so you can skip #7.   For step #8, install without the –pre flag… it will install the current official release (3.0.5 or higher).  I am not using Passenger at this time, so I can’t comment on how well that will work.  You may need to include the bundler Capistrano recipes with your deploy.rb.  This will bundle install with the –deployment flag.

I could not wait patiently for the official release of Rails 3, so I am working on a Rails 3 upgrade now… and part of the process is moving my site from co-location hosting over to Rackspace Cloud.  I am a big fan of the Rackspace Cloud and while most of my websites are hosted there now, I was waiting for my co-location contract to run up before I moved over my highest traffic website.  Here are the steps I used to set up my server. I will show you how to install all the software and create a blank Rails 3 app. Then I will show how to pull an existing Rails 3 app from github and deploy it with Capistrano.

Note: I am not doing this, but you may want to go the route of installing RVM if you will be running multiple applications or ruby versions on your production server.

My Rails stack looks like this:

  • CentOS 5.5
  • Ruby 1.9.2 preview 3
  • Rubygems 1.3.7
  • Rails 3 beta 4
  • Passenger 2.2.15 with Nginx
  • memcached
  • MySQL

Here are the steps I used.  Please leave a comment if you have any questions or if something needs to be changed.

1. Login or signup for Rackspace Cloud Servers (not Cloud Sites)
2. Build a new server – Hosting -> Cloud Servers -> Add Server -> Create a CentOS 5.5 server

(YMMV with other linux flavors using my steps)

3. Login and change your root password
4. Create a new user and add them to the sudoers file.

It is important that you create a new user instead of doing everything as root.  You will most likely run into permission problems with Passenger and Bundler if you do this as root.  Passenger will run as ‘nobody’ if ‘root’ owns the rails app root directory.  It will not have access to root’s local gem bundle. Also, go ahead and disable root login from sshd

useradd app_user
passwd app_user
vi /etc/sudoers  #open sudoers in your favorite text edit
# add the following line below "root ALL=(ALL) ALL" :
# app_user ALL=(ALL) ALL
# save file and exit

#disable root login from ssh, so nobody is able to brute force a root login
vi /etc/ssh/sshd_config
#uncomment "PermitRootLogin yes" and change it to "PermitRootLogin no"
/etc/init.d/sshd restart

#logout and login or su to your new user
su app_user
cd ~
5. Update EPEL and install linux software dependencies
sudo rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-4.noarch.rpm
sudo yum -y install gcc gcc-c++ make zlib zlib-devel openssl openssl-devel git expect pcre pcre-devel readline-devel mysql mysql-devel libxml2 libxml2-devel libxslt libxslt-devel
6. Install Ruby 1.9.2 preview 3 (compatible with Rails 3 beta 4)
wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.2-preview3.tar.gz
tar -xvf ruby-1.9.2-preview3.tar.gz
cd ruby-1.9.2-preview3
./configure
make
sudo make install
ruby -v #just checking to make sure it installed.. output = ruby 1.9.2dev (2010-05-31 revision 28117) [x86_64-linux]
cd ..
7. Install Rubygems 1.3.7
wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
tar -xvf rubygems-1.3.7.tgz
cd rubygems-1.3.7
sudo ruby setup.rb
cd ..
8. Install Ruby on Rails 3 Beta 4

If the official release is out you can remove the –pre. This should install a bunch of gems related to rails 3 beta 4 (23 gems on my system)

sudo gem install rails --pre --no-ri --no-rdoc
9. Create a new directory for your rails applications and create a blank rails app

In rails 3 you need to use the new parameter after the rails command in order to create a new app

mkdir rails_apps
cd rails_apps
rails new myapp
10. Install passenger with Nginx
sudo gem install passenger
sudo passenger-install-nginx-module
# This will guide you thru nginx/passenger install.. hit enter to check dependencies
# choose option 1. Yes: download, compile and install Nginx for me. (recommended)
# I installed in default /opt/nginx.. just hit enter to install default
# hit enter at the end and you should be finished and back to the command line prompt
11. Update your Nginx configuration file so you can run myapp with passenger.

Example Nginx config file:  /opt/nginx/conf/nginx.conf

#I found it necessary to change the user in order to have the correct permissions.
user  app_user;
worker_processes  1;
#error_log  logs/error.log;
#error_log  logs/error.log  notice;
error_log  logs/error.log  info;

events {
  worker_connections  1024;
}

http {
  #Note: rubygems installs gems in the 1.9.1 dir even though I am using 1.9.2... not sure why??
  passenger_root /usr/local/lib/ruby/gems/1.9.1/gems/passenger-2.2.15;
  passenger_ruby /usr/local/bin/ruby;
  # passenger recommends 30 max pool size if you have a 2GB box that is dedicated to app server and
  # less than that if you have a DB server running on it
  passenger_max_pool_size 30;

  include       mime.types;
  default_type  application/octet-stream;
  sendfile        on;
  #tcp_nopush     on;
  keepalive_timeout  65;
  tcp_nodelay        on;
  gzip  on;
  gzip_min_length  1100;
  gzip_buffers     4 8k;
  gzip_types       text/plain;
  gzip_comp_level 2;
  gzip_types      text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript;

  server {
    listen       80;
    server_name  localhost; #putting in localhost just for testing.  You should set this to your domain name: yourdomain.com
    root /home/app_user/rails_apps/myapp/public;
    passenger_enabled on;  #MAKE SURE YOU HAVE THIS LINE OR IT WILL NOT FORWARD TO PASSENGER!
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
       root   html;
    }
  }
}
12. Start Nginx, which will also start Passenger
sudo /opt/nginx/sbin/nginx
13. Open up iptables for port 80 and restart iptables.

Also, you might want to look into enable SELinux for some added security on your system.

sudo vi /etc/sysconfig/iptables
# Add the following line towards the bottom below the port 22 ACCEPT
# -A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
# save and close
# restart iptables
sudo /etc/init.d/iptables restart

You should be able to get to your Rails app now and see the default rails index.html -> Welcome aboard. You’re riding Ruby on Rails! ……

This is great and all, but I am more interested in running my existing app in production, rather than creating a new one. I am guessing you will not be developing on the server, so we need to get things set up with github & capistrano and deploy our app that way. This assumes that you already have a project in github and you have some git knowledge. This also assumes that you already have a database server setup and that your database.yml is pointing to that server. I will not cover database setup here.

Here is what you do:

14. Generate a new ssh key on the server to use with github
ssh-keygen -t rsa -C "youraddress@email.com"
#use the default dir and enter a solid password
15. Add the key to github

Full instructions about creating a key and adding to github here: http://help.github.com/linux-key-setup/

16. Add entry into known_hosts file for github

This is necessary to pull with capistrano. I think the easiest way to do this is to clone your github project. It will create the known_hosts file and add the entry for you. Then you can just delete the project right after you clone it. No need to keep it, since you will be using the Capistrano setup.

git clone git@github.com:your_username/your_project.git
# type yes to accept the key entry
# enter your passphrase
# it will clone.. now delete it
rm -Rf your_project/
OPTIONAL: Out of habit I have all my rails apps in the same place on my servers.

I have a dir called /rails_apps. I am going to create that now, but you can use what you already have set up if you like.  I also need to change the dir to be owned by “app_user”

sudo mkdir /rails_apps
sudo chown app_user:app_user /rails_apps/
17. Go ahead and create your project and release directory for Capistrano to use.
mkdir /rails_apps/myapp
mkdir /rails_apps/myapp/releases

IMPORTANT! It is necessary to update your nginx configuration if you are using Capistrano.  Since cap uses the “current” directory and links to a release directory, your nginx config should change the “root” entry in the server block

open /opt/nginx/conf/nginx.conf and change the “root” entry to “root /rails_app/myapp/current/public;”  Then you can restart nginx like this:

sudo killall -9 nginx
sudo /opt/nginx/sbin/nginx
18. Capistrano Setup

Now you are ready to move on to Capistrano setup. I do all development locally on my Mac, commit the code with git and push it to my repository at github. In order to use Capistrano to deploy, you will need to “gem install capistrano” on your Mac (or windows box.. say it ain’t so!) and add 2 files to your Rails project. /myapp/Capfile and /myapp/config/deploy.rb. Here are my files:

Capfile

load 'deploy' if respond_to?(:namespace) # cap2 differentiator
Dir['vendor/plugins/*/recipes/*.rb'].each { |plugin| load(plugin) }

load 'config/deploy' # remove this line to skip loading any of the default tasks

deploy.rb – most of this config came from the passenger capistrano recipe.

set :application, "myapp"

#github stuff
set :repository,  "git@github.com:your_github_id/myapp.git"
set :scm, :git
set :scm_username, "your_github_id"
set :scm_passphrase, "your_github_passwd"

set :use_sudo,    false
set :deploy_to,   "/rails_apps/#{application}"

#server login
set :user, "app_user"
set :password, "server_password_here"

ssh_options[:forward_agent] = true

# will be different entries for app, web, db if you host them on different servers
server "123.456.12.34", :app, :web, :db, :primary => true

namespace :deploy do
  task :start, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
  end

  task :stop, :roles => :app do
    # Do nothing.
  end

  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
  end
end

Now you are ready to deploy. The whole point of using Capistrano is so you don’t have to login to your servers to push code, do restarts, etc.. So on your mac, you will run the “cap” commands for deployment.

This is a 3 step process.  Run these from the command line on your development box while in your rails app root directory (dir that contains Capfile):

  1. cap deploy:check   #this will check for dependencies
  2. cap deploy:setup  #this will create your shared directories.. log, pids, system
  3. cap deploy  #this will pull your code from github and put it in a new release directory, create a link to “/rails_apps/myapp/current” directory for that release and restart your passenger server

Now, take a look at your app on the server.  If you are lucky it will be running as expected, but I highly doubt it if you have gems that need to be installed.  Lets use bundler to get the necessary gems installed.  If you are Rails 3 savvy, you know that all your gem dependencies should be in /myapp/Gemfile, and that you can use Bundler (which is awesome BTW.. thnx wycats) to install them easily.

Passenger gives me a real pretty screen that says: “Could not find gem ‘mysql (= 2.8.1, runtime)’ in the gems available on this machine. (Bundler::GemNotFound)”

My Gemfile contains that gem, but it is not on my server.  So to get Bundler to install it, you will need to navigate over to your rails app root directory on the server. I mentioned earlier that you should not set up your rails app with the ‘root’ account on your linux box, and this is the problem that I ran into. When I installed with bundler, it put the bundled gems in /root/.bundle/…. and the web server could not access the gems, because passenger runs as ‘nobody’. If you run the server as ‘app_user’ or whatever you account is, then you should bundle install with the same account, so you dont have permission problems.

cd /rails_apps/myapp/current
bundle install  #no need for sudo here.  You want them to install in your user's home dir
19. Memcached Setup

Next on my list was getting memcached working. I use memcached as my cache store. In /myapp/config/environments/production.rb, I have the following line:

config.cache_store = :mem_cache_store

So passenger was complaining about not having memcached -> no such file to load — memcache

First I need to install memcached on the server. You can use a seperate server for memcached but you need to update the line in production.rb, to point to that server. It uses localhost by default.
In order to get memcached to work, you have to install libevent first

cd
wget http://www.monkey.org/~provos/libevent-1.4.13-stable.tar.gz
tar -xvf libevent-1.4.13-stable.tar.gz
cd libevent-1.4.13-stable
./configure && make
sudo make install
cd ..
wget http://memcached.googlecode.com/files/memcached-1.4.5.tar.gz
tar -xvf memcached-1.4.5.tar.gz
cd memcached-1.4.5
./configure && make
sudo make install
#you will get errors if you do not do the next 2 steps.  Create libevent config file, add a line to it, and then run ldconfig
sudo vi /etc/ld.so.conf.d/libevent-i386.conf  #create this file and add one line ->
                                                              # /usr/local/lib/
sudo /sbin/ldconfig
#start your memcached server up
sudo /usr/local/bin/memcached -u nobody &
#you should add this last command to /etc/rc.local so the memcached server starts if there is a reboot

Now your memcached server is running, but you still have to install the gem. Let’s add it to our Gemfile, git commit, & git push on our Mac, run “cap deploy” and then bundle install again on the server

#Gemfile located at myapp/Gemfile. on your dev box
group :production do
gem “memcache-client”
end

One note of caution here.. if you are already in /rails_apps/myapp/current, you need to cd again. If I remember correctly I ran into the problem of being in an old release directory. I guess when the link was update, my shell did not catch the update and was pointing current to the previous release directory.

cd /rails_apps/myapp/current
bundle install

You should have a working Rails app with memcached now. I did run into one gotcha when I was doing this. I had a legacy Rails app that I was upgrading and the following line was in environments/production.rb:

config.action_view.cache_template_loading = true

This line needs to be removed if you get the following error -> “undefined method `cache_template_loading=’ for ActionView::Base:Class”

Now open up your app in your browser and feel all the Rails 3 goodness! You are a rock star!

Hopefully YMDNV ;-)   Everything seems to be working so far on Rails 3 and I have a fairly complex app with quite a few plugins.  I think the hardest part about adopting Rails 3 is the fact that plugins are not ready.  I spent a good bit of my time troubleshooting and patching (yeah.. some monkey stuff) plugins.  You can read more about my upgrade experiences in this post.

Tags: , , , , ,

Rails 3 Upgrade.. my experience

UPDATE 1 (6/29/2010): Today I purchased a copy of “Rails 3 Upgrade Handbook” by Jeremey McAnally, who wrote the rails_upgrade plugin.  I would highly recommend reading this book as your starting point for Rails 3 upgrade, as I wish I read this before I started my upgrade.  He goes into alot of detail about what you need to change.  The steps differ some from what I wrote in this post, and you might find it easier to follow his steps.

This is going to be quite a long post and I will probably be updating it daily for the next few weeks.  Now that Rails 3 RC is right around the corner, I figured it would be a good time to upgrade CouponShack.com.  I have been meaning to refactor my code for quite a while and clean up the mess I have created in the last 3 years.   I am finally getting around to it and I thought upgrading to Rails 3 would be a good start, so here is my experience upgrading to Rails 3, from Rails 2.3.2.  I am writing some of this after the fact, so hopefully I didn’t leave out any steps:

Current stable setup on CouponShack.com

  • Co-location hosting in my city
  • CentOS 5
  • nginx
  • Mongrel 1.1.5
  • Rails 2.3.2
  • Ruby 1.8.7

Proposed upgrade

  • Rackspace Cloud Servers hosting
  • Rails 3 beta4 (upgrade to RC when ready)
  • Ruby 1.9.2dev
  • New app server… looking at Passenger right now

The upgrade list may change depending on how everything pans out.  I was planning on moving over to Rackspace Cloud (where most of my other apps are currently), so I figured I would go with Rails 3 as a part of that move.

Note: I use Mac OSX 10.5.8 and Textmate for development

Another Note: A good place to start is to read the Rails 3 Release Notes.  This document explains the new features, upgrade path, and has alot of good links to blog posts by the rails developers that relate to the new features.  My blog post reiterates alot of this info while showing you how it relates to my specific upgrade.  I recommend reading as much as you can about Rails 3 before you get your feet wet with the upgrade… I know that helped me.

Upgrade Steps

Step 1 – Install RVM

RVM will allow you to run multiple versions of Ruby on your development box.  This is a must if you are upgrading to Rails 3 and still want to use Rails 2.  Follow the instructions on the RVM website and install it from github.

Step 2 – Install Ruby 1.9.2

After RVM is installed, you will want to install Ruby 1.9.2 using RVM.

rvm install 1.9.2

It will take a few minutes.  On my system it installed ruby-1.9.2-preview3. After its done you can switch to 1.9.2 by using this command.

rvm 1.9.2

Now your Mac is using 1.9.2 instead of the system ruby (you can switch back with “rvm system” if you need to code some rails 2 stuff again)

Step 3 – Install Rails 3

Using Ruby 1.9.2 on your system, you can now install Rails 3.  One thing to note here is that you now have a clean slate for all your gems.  RVM conveniently stores your gems in a directory under your account ~/.rvm/gems/ruby-1.9.2-preview3/gems.  This will allow you to keep your Rails 2 gems separate, but that means that you have to reinstall any gems that you might be using in your Rails 2.3 app.  You will probably get plenty of errors when you finally start up your app as a result of the missing gems… I will get into that later.  So here is all you need to do to install the Rails 3 beta 4.

sudo gem install rails --pre

You should be set now with Rails 3.  You can do a version check just to be sure with “rails -v”.

Step 4 – Generate a blank Rails 3 application

NOTE: If you don’t have your app in a source control repository, it may be a good idea to also make a full backup of your app directory before you start changing things.

I found it useful to have a blank Rails 3 app to use as a reference when upgrading my 2.3 app.  You will most likely need to drop some of the files in your 2.3 app or at least copy/paste some of the code.  Create the new app with the rails command in your terminal.

rails new blank_app

Step 5 – Get the rails_upgrade plugin and run it

This is an officially supported plugin from Rails.  Get it here: http://github.com/rails/rails_upgrade Jeremy McAnally has instructions on how to install rails_upgrade as a plugin.  I remember seeing this was opted as a plugin instead of a gem because it was easy to install and delete from your application.

I ran the check rake task first after I installed this plugin.  It gave me quite a large list of things I need to change.  Most of the changes involved the new ActiveRecord Query API, which is pretty awesome btw.  I just ran down the list one by one and changed what it was complaining about.  I re-ran it after every section to make sure the changes were correct.  There are a few other Rake tasks to add the new Gemfile, add the application.rb and fix your routes, but I opted to do that manually in order to learn more about the changes.

I am guessing you may spend alot of time updating queries and scopes, so check out these blogs from some of the Rails gurus for more info on what has changed in Rails 3 and when the old stuff will be deprecated:

http://m.onkey.org/2010/1/22/active-record-query-interface

http://hasmanyquestions.wordpress.com/2010/01/17/let-your-sql-growl-in-rails-3/

Step 6 – Remove your old scripts and add the new rails script

Rails 3 has replaced all the scripts in /app_root/script with a single script called rails.  I deleted all of the files in the script directory and copied the file from my blank application in step 4 and put the file in my script directory.  I think it makes much more sense for rails to have one script file.  This file can start the server, generate scaffolding,  start your console etc..  To see a full list of commands use “rails –help” inside your application somwhere.

Step 7 – Upgrade your environment files (rails_upgrade may take care of this)

The individual environment files in config/environments/ are also a little different in Rails 3.  I am not sure if rails_upgrade takes care of this, but I did not use that rake task, so I just updated the files manually.  You will need to add a block around your configuration in each of these files.  Mine looks something like this for development.rb:

Couponshack::Application.configure do
  config.cache_classes = false
  #.....
end

Also, make sure you update your environment.rb file if rails_upgrade didn’t do it for you.  Refer to the blank application in step 4 for the code… its only a couple of lines now.

Step 8 – Add application.rb (rails_upgrade will do this for you)

If you want to do this manually to see whats new, check out the application.rb file in your blank app.  There are examples in the comments.  For those that don’t know, application.rb is sort of a replacement for environment.rb.  This file is for application specific configuration and it makes sense that they would remove this from environment.rb, since application and environment configuration are really 2 completely separate things.. app configuration is not specific to an environment.

Step 9 – New routes (rails_upgrade will do this for you)

Rails 3 has new syntax and features for the routes file.  Look at config/routes.rb in the blank app you created in step 4.  The comments provide you with an explanation of the new route syntax.  Some of the highlights include shortened syntax for controller/action.  Instead of :controller=>”mycontroller”, :action=>”myaction”, you would write – :to=>”mycontroller#myaction”.   And new syntax for mapping..  instead of “map.connect” or “map.name_of_route”, you just use “match” (and :as=>”name_of_route”).  I would recommend doing this reading all the comments in the new file and doing it manually so you can learn the new syntax, unless of course you have hundreds of routes.

Step 10 – Take care of them Gems (rails_upgrade can do this too)

Along with application specific configuration, Gem config was also removed from environment.rb in favor of the Gemfile which is in the application root directory.  Again, take a look at a blank Rails 3 app to see what this file should look like.  The gemfile makes gem dependency management easy by using the new bundler.  Bundler checks your system for installed gems based on the Gemfile and can install them for you automatically.  If you try to start up your app and you are missing a gem dependency, you will see something like this:

Could not find gem 'mechanize (>= 0, runtime)' in the gems available on this machine.
Try running `bundle install`.

The Gemfile and Bundler are great additions to Rails 3.  For more info check out the bundler home page for more info on what it can do.

I know many of you will run into problems with existing Gems that are not quite Rails3 ready.  Hopefully most of the popular gems and plugins will be finished with the upgrade by the time the official release comes out… probably wishful thinking.  A good resource for troubleshooting problems with Gem and plugin compatibility with Rails 3 is this website:  RailsPlugins.org – Lots of comments have been posted on this site and more than likely someone has already experienced the upgrade problem that you may be having.  It was helpful in troubleshooting a few of the plugin bugs I found.

Step 11 – Beware: “h” helper in views is the default now

This is turned on by default now.  So you don’t have to do crap like this anymore: <%= h @blog.title %>.  The “h” is not necessary, so HTML will be escaped by default.  If you have any content that includes HTML coming from your database, you will need to wrap that with the “raw” method like so: <%= raw(@blog.html_enabled_content) %>

Step 12 – config.ru

Rack-based servers use this file to start the app, so you will probably want to add this if you have not already.  Again, copy the file from the blank app and change the application name.

Step 13 – Start up your app locally and pray

Mine did not work at all.  I use mongrel on my dev box and I had trouble running it manually (mongrel_rails start).  Then I used the rails server command and it seemed to work fine.  You can start it up by using the new rails script file.  All you have to do is type:

rails s

This will start up the server locally and you are ready to take a look at your app.

As far as a I remember, these are the steps necessary for my app to start running on my Mac.  If I left out anything, please comment on this post.  The rest of this post will go into detail on some of the problems I am having and how I solved them, as well as the upgrade path on my production server.  At the time of this writing I am planning on using Nginx in front of Passenger for my production environment.

Problems that I ran into (mainly plugins)

Problem 1 – recaptcha plugin

I was using this in vendor/plugins.  It when I tried to access pages that used this helper, it was complaining about “builder” not being available or something to that effect.  I monkeypatched the code in /plugins/vendor/recaptcha/lib/recaptcha.rb – added the following line to the top:

require 'builder'

recaptcha_tags worked in the views after I added that line.

Problem 2 – will_paginate errors

I was getting this annoying error:

undefined method `paginate' for #<Class:0x16c739c>

activerecord (3.0.0.beta4) lib/active_record/base.rb:1041:in `method_missing'

I included will_paginate in my Gemfile with this line:

gem "will_paginate", :git => "git://github.com/mislav/will_paginate.git", :branch => "rails3"

That did not fix it.  Same error.  I finally realized that I screwed up application.rb when I was upgrading.  I was missing the bundler require call, so the initializers in the railtie were never executed.  Make sure you have this in your application.rb, or your dependencies will probably crap out.

# If you have a Gemfile, require the gems listed there, including any gems
# you've limited to :test, :development, or :production.
Bundler.require(:default, Rails.env) if defined?(Bundler)

Problem 3 – equals sign with blocks

When running rails_upgrade, it warned me of several blocks that needed an equals sign. This is new to Rails 3 and it makes sense now that I understand where to use it.  Basically if it spits out a tag or any output to the view, then you should use equals, otherwise if its an .each iterator or something like that that does not produce output don’t use it.  Some of these were false positives like the following:

<% @blogs.each do |blog| %>

Check out Ryan Bates screencast which shows when to use and not use the equals.  I am not sure if this has been fixed in the rails_upgrade plugin, but its something worth noting.  It was spitting out the printed representation of the objects when I used an equals with it.. not pretty ;-)

Problem 4 – my routes.rb is too bloated

rails_upgrade does a very good job of translating your routes.rb into the new syntax for the most part.  This is not a huge deal, but the only part I wanted to change was the way the collection section is written.  My routes.rb after the upgrade was hundreds of lines long.  My legacy code (which needs to be big-time refactored) has lots of collections for my resources.  This was a result of Rails 1 code being merged with Rails 2 code.. I used the collection hash in my resources to add any controller/action that was not RESTful.. and I had lots from my original Rails 1 app.. mostly custom views which could have been consolidated in the show or index action.  But anyways, all these collection members produce something that looks like this:

resources :blogs do
  collection do
    get :action1
    get :action2
    get :action3
    #...... etc.........
  end
end

After experimenting I found out that Rails 3 also accepts this form:

resources :blogs do
  collection do
    get :action1, :action2, :action3 #etc...
  end
end

Just personal preference, but I find this form much easier to manage because of the large number of collection actions that I have.. refactoring them is a whole different story.

Problem 5 – colon in case statement (caused by new Ruby version)

I use the little known, “date_time_text_field_helpers” plugin.  Long name, but came in handy for handling some of my date/time fields.  When I tried to start my app server with Rails 3 it gave me the following error:

/rails_apps/couponshack/vendor/plugins/date_time_text_field_helpers/lib/date_time_text_field_helpers/instance_tag.rb:110: syntax error, unexpected ':', expecting keyword_then or ',' or ';' or '\n' (SyntaxError)
when :hour, :minute, :second : 2

So I looked at instance_tag.rb at line 110 and I see a syntax that I did not recognize in a case statement. I rarely use case statements and I don’t know much about them, but apparently Ruby 1.8x allowed the use of the colon character. This has been deprecated in Ruby 1.9. I changed the colons to “then”. Another problem is the html escaping. I had to update a call to content_tag and pass escape=false. You can check out the changes in my github fork:
http://github.com/johnmcaliley/date_time_text_field_helpers/commit/ba14af26781ac2576f20f0195703fad2c9657082#diff-0

Works just fine now.

more to come…


Tags: , ,