Migration from Rails 2 to Rails 3



                      Abdullah Muhammad
                           Haseeb Ahmad
                            Nadeem Yasin
                              Umair Amjad
Table of Contents
Introduction to the New features in Rails 3
Differences between Rails 2 and Rails 3
Migration of Rails 2 app to Rails 3
Core New Features
Rails 3.0
Brand new router
Explicit dependency management with Bundler


Rails 3.1
Reversible Migrations
Assets Pipeline
jQuery as the default JavaScript library


Rails 3.2
Faster Development Mode
New Routing Engine
Automatic Query Explains
Tagged Logging
Rails 3.0
Brand new router
       Routes defined by each application are now name spaced within your Application module

       Instead of                                                                 We use
ActionController::Routing::Routes.draw do |map|                        AppName::Application.routes do
 map.resources :posts                                                            resources :posts
end                                                                   end

1. Added match method to the router
match "/main/:id", :to => "main#home"
2. Added scope method to the router, allowing you to namespace routes for different languages or different actions
scope 'es' do
   resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'proyecto'
end
# Gives you the edit action with /es/proyecto/1/cambiar

3. Added constraints method to the router, allowing you to guard routers with defined constraints.
       match "/foo/bar", :to => "foo#bar", :constraints => {:subdomain => "support"}

4. Added root method to the router as a short cut for match ‘/’, :to => path.
root :to => "foo#bar"



The old style map commands still work as before with a backwards compatibility layer, however this will be           removed in the 3.1 release.
Rails 3.0 Cont'd
endency management with Bundler

 uses a Gemfile in the application root to determine the gems you require   for your application to start.
s processed by the Bundler, which then installs all your dependencies

em is dead, long live bundler
 and their brother complained about Rails’ handling of vendored/bundled gems since config.gem was added

 m "RedCloth", :lib =>'redcloth', :version=>">= 4.0"
dCloth", ">= 4.0", :require =>'redcloth'
 create a Gemfile, you simply have to run "bundle" pack and you're done!
Rails 3.1
 line
  or compress JavaScript and CSS assets


 ript files into one master.js file and all CSS files   into one master.css file.

 hitespace and comments. For JavaScript, more           complex processes can be applied. You can choose from a
 vel language
SS, CoffeeScript for JavaScript, and ERB for both by    default.
mpressed and minified by one central library,           Sprockets. It is enabled by default. It can be disabled in con


 like fingerprinting at production environment
Rails 3.1 Cont'd
ery as the default JavaScript library
    jQuery is the default JavaScript library that ships with Rails 3.1. But if you use Prototype, it’s simple to switch.
    $ rails new myapp -j prototype
    Prototype are no longer vendored and is provided from now on by the prototype-rails gems.

versible Migrations
    Migrations are now reversible, meaning that Rails will figure out how to reverse your migrations
    To use reversible migrations, just define the change method.
     class MyMigration < ActiveRecord::Migration
  change
 eate_table(:horses) do |t|
 .column :content, :text
 .column :remind_at, :datetime
nd
d

e commands like remove_column cannot be reversed. If you care to define how to move up and down in these cases, you should define the up and down methods as be
Rails 3.2
 atic Query Explains
 comes with a nice feature that explains queries generated by ARel by defining an explain method in ActiveRecord::Relation.
mple,

 .order(:name).explain
oad (0.6ms) SELECT "products".* FROM "products" ORDER BY name
(0.1ms) EXPLAIN QUERY PLAN SELECT "products".* FROM "products" ORDER BY name
AIN for: SELECT "products".* FROM "products" ORDER BY namen0|0|0|SCAN TABLE products (~1000000 rows)n0|0|0|USE TEMP B-TREE FOR ORDER BYn

 Logging
nning a multi-user, multi-account application, it’s a great help to be able to filter the log by who did what
 ogging in Active Support helps in doing exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such app
Differences
old scripts        new hotness
script/generate      rails g
script/console       rails c
script/server        rails s
script/dbconsole     rails db
New Router API
map.resources :posts do |post|
       post.resources :comments
 end
resources :posts do
       resources :comments
 end

NAMED ROUTES
map.connect 'login', :controller => 'session', :action => 'new'
match 'login' => 'session#new'

LEGACY ROUTES
map.connect ':controller/:action/:id'
map.connect ':controller/:action/:id.:format'

match ':controller(/:action(/:id(.:format)))'

 map.root :controller => "users"
root :to => "users#index"
ActionController - respond_with
class UsersController < ApplicationController
def index
        @users = User.all
respond_to do |format|
               format.html
               format.xml { render :xml => @users.to_xml }
end
end

.....

class UsersController < ApplicationController
respond_to :html, :xml, :json
def index
        @users = User.all
respond_with(@users)
end
Model
@posts = Post.find(:all, :conditions => {:published => true} , :limit => 10)
@posts = Post.where(:published => true).limit(10)

Post.find(:all, :conditions => {:author => "Joe"}, :includes => :comments, :order => "title", :limit => 10)
Post.where(:author => "Joe").include(:comments).order(:title).limit(10)

REFACTOR
@posts = Post.where(:published => true)
@posts = @posts.order(params[:order])

@posts = Post.where(:published => true).order(params[:order])
Model Cont'd
@published = Post.published
@unpublished = Post.unpublished

class Post < ActiveRecord::Base
 default_scope :order => 'title'
 named_scope :published, :conditions => {:published => true}
 named_scope :unpublished, :conditions => {:published => false}
end

class Post < ActiveRecord::Base
 default_scope order('title')
 scope :published, where(:published => true)
 scope :unpublished, where(:published => false)
end
Action View
Cross-Site Scripting (XSS)
<%= h @post.body %>
<%= raw @post.body %>

<%= link_to_remote 'Show', :url => post %>
<a href="#" onclick="new Ajax.Request('/posts/1', {asynchronous:true,
evalScripts:true, parameters:'authenticity_token=' +
encodeURIComponent('9sk..44d')}); return false;">Show</a>

<%= link_to 'Show', post, :remote => true %>
<a href="/posts/1" data-remote="true">Show</a>

<% remote_form_for(@post) do |f| %>
<form action="/posts" class="new_post" id="new_post" method="post"
onsubmit="new Ajax.Request('/posts', {asynchronous:true,
evalScripts:true, parameters:Form.serialize(this)}); return false;">

<% form_for(@post, :remote => true) do |f| %>
<form action="/posts" class="new_post" data-remote="true" id="new_post" method="post">
Deprecated Methods
link_to_remote
      # link_to "Somewhere", '/posts/1', :remote => true
# <a href="/posts/1" data-remote="true">Somewhere</a>
remote_form_for
observe_field
observe_form
form_remote_tag
button_to_remote
submit_to_remote
link_to_function
periodically_call_remote

prototype_legacy_helper
https://github.com/rails/prototype_legacy_helper
Migration from Rails2 to Rails3
rvm install 1.9.2
rvm use 1.9.2@Rails3 --create
rvm gemset list
gem install rails -v=3.1.3
script/plugin install git://github.com/rails/rails_upgrade.git
rake rails:upgrade:check
rake rails:upgrade:backup
rvm 1.9.2
rails new . -d mysql
bundle install
rails s

Migration from Rails2 to Rails3

  • 1.
    Migration from Rails2 to Rails 3 Abdullah Muhammad Haseeb Ahmad Nadeem Yasin Umair Amjad
  • 2.
    Table of Contents Introductionto the New features in Rails 3 Differences between Rails 2 and Rails 3 Migration of Rails 2 app to Rails 3
  • 3.
    Core New Features Rails3.0 Brand new router Explicit dependency management with Bundler Rails 3.1 Reversible Migrations Assets Pipeline jQuery as the default JavaScript library Rails 3.2 Faster Development Mode New Routing Engine Automatic Query Explains Tagged Logging
  • 4.
    Rails 3.0 Brand newrouter Routes defined by each application are now name spaced within your Application module Instead of We use ActionController::Routing::Routes.draw do |map| AppName::Application.routes do map.resources :posts resources :posts end end 1. Added match method to the router match "/main/:id", :to => "main#home" 2. Added scope method to the router, allowing you to namespace routes for different languages or different actions scope 'es' do resources :projects, :path_names => { :edit => 'cambiar' }, :path => 'proyecto' end # Gives you the edit action with /es/proyecto/1/cambiar 3. Added constraints method to the router, allowing you to guard routers with defined constraints. match "/foo/bar", :to => "foo#bar", :constraints => {:subdomain => "support"} 4. Added root method to the router as a short cut for match ‘/’, :to => path. root :to => "foo#bar" The old style map commands still work as before with a backwards compatibility layer, however this will be removed in the 3.1 release.
  • 5.
    Rails 3.0 Cont'd endencymanagement with Bundler uses a Gemfile in the application root to determine the gems you require for your application to start. s processed by the Bundler, which then installs all your dependencies em is dead, long live bundler and their brother complained about Rails’ handling of vendored/bundled gems since config.gem was added m "RedCloth", :lib =>'redcloth', :version=>">= 4.0" dCloth", ">= 4.0", :require =>'redcloth' create a Gemfile, you simply have to run "bundle" pack and you're done!
  • 6.
    Rails 3.1 line or compress JavaScript and CSS assets ript files into one master.js file and all CSS files into one master.css file. hitespace and comments. For JavaScript, more complex processes can be applied. You can choose from a vel language SS, CoffeeScript for JavaScript, and ERB for both by default. mpressed and minified by one central library, Sprockets. It is enabled by default. It can be disabled in con like fingerprinting at production environment
  • 7.
    Rails 3.1 Cont'd eryas the default JavaScript library jQuery is the default JavaScript library that ships with Rails 3.1. But if you use Prototype, it’s simple to switch. $ rails new myapp -j prototype Prototype are no longer vendored and is provided from now on by the prototype-rails gems. versible Migrations Migrations are now reversible, meaning that Rails will figure out how to reverse your migrations To use reversible migrations, just define the change method. class MyMigration < ActiveRecord::Migration change eate_table(:horses) do |t| .column :content, :text .column :remind_at, :datetime nd d e commands like remove_column cannot be reversed. If you care to define how to move up and down in these cases, you should define the up and down methods as be
  • 8.
    Rails 3.2 aticQuery Explains comes with a nice feature that explains queries generated by ARel by defining an explain method in ActiveRecord::Relation. mple, .order(:name).explain oad (0.6ms) SELECT "products".* FROM "products" ORDER BY name (0.1ms) EXPLAIN QUERY PLAN SELECT "products".* FROM "products" ORDER BY name AIN for: SELECT "products".* FROM "products" ORDER BY namen0|0|0|SCAN TABLE products (~1000000 rows)n0|0|0|USE TEMP B-TREE FOR ORDER BYn Logging nning a multi-user, multi-account application, it’s a great help to be able to filter the log by who did what ogging in Active Support helps in doing exactly that by stamping log lines with subdomains, request ids, and anything else to aid debugging such app
  • 9.
    Differences old scripts new hotness script/generate rails g script/console rails c script/server rails s script/dbconsole rails db
  • 10.
    New Router API map.resources:posts do |post| post.resources :comments end resources :posts do resources :comments end NAMED ROUTES map.connect 'login', :controller => 'session', :action => 'new' match 'login' => 'session#new' LEGACY ROUTES map.connect ':controller/:action/:id' map.connect ':controller/:action/:id.:format' match ':controller(/:action(/:id(.:format)))' map.root :controller => "users" root :to => "users#index"
  • 11.
    ActionController - respond_with classUsersController < ApplicationController def index @users = User.all respond_to do |format| format.html format.xml { render :xml => @users.to_xml } end end ..... class UsersController < ApplicationController respond_to :html, :xml, :json def index @users = User.all respond_with(@users) end
  • 12.
    Model @posts = Post.find(:all,:conditions => {:published => true} , :limit => 10) @posts = Post.where(:published => true).limit(10) Post.find(:all, :conditions => {:author => "Joe"}, :includes => :comments, :order => "title", :limit => 10) Post.where(:author => "Joe").include(:comments).order(:title).limit(10) REFACTOR @posts = Post.where(:published => true) @posts = @posts.order(params[:order]) @posts = Post.where(:published => true).order(params[:order])
  • 13.
    Model Cont'd @published =Post.published @unpublished = Post.unpublished class Post < ActiveRecord::Base default_scope :order => 'title' named_scope :published, :conditions => {:published => true} named_scope :unpublished, :conditions => {:published => false} end class Post < ActiveRecord::Base default_scope order('title') scope :published, where(:published => true) scope :unpublished, where(:published => false) end
  • 14.
    Action View Cross-Site Scripting(XSS) <%= h @post.body %> <%= raw @post.body %> <%= link_to_remote 'Show', :url => post %> <a href="#" onclick="new Ajax.Request('/posts/1', {asynchronous:true, evalScripts:true, parameters:'authenticity_token=' + encodeURIComponent('9sk..44d')}); return false;">Show</a> <%= link_to 'Show', post, :remote => true %> <a href="/posts/1" data-remote="true">Show</a> <% remote_form_for(@post) do |f| %> <form action="/posts" class="new_post" id="new_post" method="post" onsubmit="new Ajax.Request('/posts', {asynchronous:true, evalScripts:true, parameters:Form.serialize(this)}); return false;"> <% form_for(@post, :remote => true) do |f| %> <form action="/posts" class="new_post" data-remote="true" id="new_post" method="post">
  • 15.
    Deprecated Methods link_to_remote # link_to "Somewhere", '/posts/1', :remote => true # <a href="/posts/1" data-remote="true">Somewhere</a> remote_form_for observe_field observe_form form_remote_tag button_to_remote submit_to_remote link_to_function periodically_call_remote prototype_legacy_helper https://github.com/rails/prototype_legacy_helper
  • 16.
    Migration from Rails2to Rails3 rvm install 1.9.2 rvm use 1.9.2@Rails3 --create rvm gemset list gem install rails -v=3.1.3 script/plugin install git://github.com/rails/rails_upgrade.git rake rails:upgrade:check rake rails:upgrade:backup rvm 1.9.2 rails new . -d mysql bundle install rails s