SlideShare a Scribd company logo
Rails 3
 (beta)
Roundup
  April 6, 2010
Why Upgrade
• Performance
  tighter & faster codebase, relational optimizations, shorter path to response, better scaling, better use of Rack & Middleware




• Security
  better routing DSL, XSS protection, more powerful controller stack, better use of Rack & Middleware, fixes




• Labour-savings
  easier routing, reliable gem management, easier Ajax, better code reuse, less monkey-patching, better & easier generators




• Modernization
  Rack reliance, later Ruby, plug in new frameworks and components, new standards




• Cost saving
  lower hardware requirements, less Gem maintenance, consistency means easier for developers
HTTP://GUIDES.RAILS.INFO/3_0_RELEASE_NOTES.HTML




                Significant Features
      • Dependency management with Bundler

      • More concise router

      • Chainable database query language

      • New ActionMailer API

      • Unobtrusive JavaScript

      • Better modularity

      • Improved XSS protection
Bundler
              http://railscasts.com/episodes/201-bundler

                                                         get used to version juggling for now


                           gem "rails", "3.0.0.beta"
• all gems listed in       # gem "rails", :git => "git://github.com/rails/
  Gemfile                   rails.git"

                           gem "sqlite3-ruby", :require => "sqlite3"

• ‘setup’ gemfile           # gem "rspec", :group => :test
                           group :test do
                             gem "webrat"
                           end
• ‘install’
                           gem install bundler
                           bundle setup
• ‘pack’                   bundle install
                           bundle unlock
                           mate Gemfile
                           bundle install --without=test
• deploy app               bundle pack


                           # application.rb

• unlock to modify         require 'rails/all'

                           Bundler.require(:default, Rails.env) if defined?(Bundler)



                                            Need version 9+. No config.gem required for Rails 3, although some need it for Rails 2.
New Modular
               Architecture
• “Railties framework is now a set of individual Railties, each
  inheriting from a new class, Rails::Railtie”

• Third-party plugins hook into early stages of initialization

• Rake tasks and generators part of the frameworks

• “In short, Rails frameworks are now plugins to Rails”

  Action Mailer * Action Pack * Active Record *
      Active Resource * Active Model * Active
                      Support
• And features like ActiveRecord validations and serialization
  reusable, eg: include ActiveModel::Validations
Routing
                   resources :products do  

• more concise      get :detailed, :on => :member 
                   end 
                          block
                   resources :forums do  

  DSL               collection do  
                      get :sortable  
                      put :sort 
                    end  
                    resources :topics

• rack routes      end

                   match "/secret" => "info#about", :constraints => { :user_agent => /Firefox/ }


                   constraints :host => /localhost/ do  

• constraints       match "/secret" => "info#about"  
                    match "/topsecret" => "info#about"  
                   end 

                   match "/hello" => proc { |env| [200, {}, "Hello Rack!"] }

• other features   root :to => "home#index"

                   match "/about" => "info#about", 
                    :as => :about
Controllers
•   taller stack abstracting
    rendering, layouts, rack,      AbstractController::Base
    etc
                                   ActionController::Metal
•   enhance by subclassing




                                                                    New
    relevant layer                  ActionController::Base




                                                              Old
•   middleware layer                ApplicationController

•   ‘respond_with(@post)’               MyController

•   flash[:notice] & flash[:alert]
ActionMailer
• like a controller            r g mailer UserMailer welcome

                                            gives...
• email types like
  actions               class UserMailer < ActionMailer::Base

                              def welcome(user, subdomain)
                                @user = user
• mail() to send                @subdomain = subdomain

                                mail(:from => "admin@testapp.com",
                                 :to => @user.email,
• no ‘deliver_’ prefix            :subject => "Welcome to TestApp")

                              end
• mail() do..end for
                        end
  multipart
More ActionMailer
class UserMailer < ActionMailer::Base

      default   :from => "admin@testapp.com"

      def welcome(user, subdomain)
        @user = user
        @subdomain = subdomain

        attachments['test.pdf']      = File.read("#   {Rails.root}/public/test.pdf")

        mail(:to => @user.email, :subject => "Welcome to TestApp") do |format|
         format.html    { render 'other_html_welcome' }
         format.text { render 'other_text_welcome' }
        end
      end

end
More ActionMailer
class UserMailer < ActionMailer::Base

      default   :from => "admin@testapp.com"

      def welcome(user, subdomain)
        @user = user
        @subdomain = subdomain

        attachments['test.pdf']      = File.read("#   {Rails.root}/public/test.pdf")

        mail(:to => @user.email, :subject => "Welcome to TestApp") do |format|
         format.html    { render 'other_html_welcome' }
         format.text { render 'other_text_welcome' }
        end
      end

end
Models
• New ActiveModel
                      MyClass
• Encapsulates         ActiveModel::Validations

  features
                           Serialization
                       ActiveModel::Observing

• ‘include’ in non-
                       ActiveModel::Serialization
  ActiveRecords
                               etc..
• also...
Find and Scopes
• Relational algebra   # Article.find(:all, :order => "published_at
                       desc", :limit => 10)
                       Article.order("published_at desc").limit(10)

• chained methods      # Article.find(:all, :conditions => ["title = ?",
                       ‘This’], :include => :comments)
                       Article.where("title = ?",

• named_scope now      ‘This’).includes(:comments)



  scope                # Article.find(:first, :order => "published_at
                       desc")
                       Article.order("published_at").last


• conditions now       # models/active_record.rb
                       scope :visible, where("hidden != ?", true)
  where                scope :published, lambda { where("published_at
                       <= ?", Time.zone.now) }
                       scope :recent, visible.published.order("published_at
                       desc")

• deferred retrieval
ActiveRelation Methods
                  •      where                          •    limit
                  •      select                         •    joins
                  •      order                          •    group
                  •      offset                         •    having
                  •      includes                       •    lock
                  •      readonly
                  •      from
Book.where(:author => "Austen").include(:versions).order(:title).limit(10)
Executed only when the data is needed
In Views
                                   <%= form_for @product do |f| %>
• ‘=’ required for all tags        <% end %>

  that output content              <%= div_for @product do %>
                                   <% end %>

  including blocks, like           <% @comments.each do |c| %>
                                   <% end %>
  ‘form_for’
                                   <% content_for :side do %>
                                   <% end %>

• ‘-’ no longer required           <% cache do %>
                                   <% end %>
  to suppress spaces
                              
                              <%= admin_area do %>
• write_output_buffer           <%= link_to "Edit", edit_product_path(@product) %> |
                                <%= link_to "Destroy", @product, :confirm => "Are you
                              sure?", :method => :delete %> |
  method in helpers             <%= link_to "View All", products_path %>
                              <% end %>

                              # application_helper.rb

• no ‘=’ for cache helper     def admin_area(&block)
                                content = with_output_buffer(&block)
                                content_tag(:div, content, :class => "admin")
                              end
XSS Protection
• ‘h’ assumed
                           
                           <div class="comment">
• new ‘raw’ method to      %>
                             <%= strong link_to(comment.name, comment.url)


  unescape                    <p><%= comment.content %></p>
                           </div>

                           # rails c
• html_safe? and           "foo".html_safe?
                           safe = "safe".html_safe
                           safe.html_safe?
  html_safe method to
                           # application_helper.rb
  check/make string safe   def strong(content)
                             "<strong>#{h(content)}</strong>".html_safe
                           end

• ‘html_safe’ must be
  used on helper output
Unobtrusive Javascript
                           
                           <% form_tag products_path, :method => :get, :remote => true do
• Makes use of ‘data-      %>
                              <p>

  remote’ tag for Ajax forms    <%= text_field_tag :search, params[:search] %>
                                <%= submit_tag "Search", :name => nil %>
                              </p>
                           <% end %>

• Other Javascript tag     <a href="#" id="alert" data-message="Hello UJS!">Click Here</a>


  ‘data-’ attributes       <%= link_to 'Destroy', post, :method => :delete %>



  supported                       In rails.js
                                  document.observe("dom:loaded", function() {

                                    $(document.body).observe("click", function(event) {

• http://github.com/rails/              var message = event.element().readAttribute('data-confirm');
                                        if (message) {

  jquery-ujs                            }
                                          // ... Do a confirm box



                                        var element = event.findElement("a[data-remote=true]");
                                        if (element) {


• http://github.com/rails/
                                          // ... Do the AJAX call
                                        }

                                        var element = event.findElement("a[data-method]");

  prototype_legacy_helper               if (element) {
                                          // ... Create a form
                                        }

                                  });
The Commandline
  • rails s[erver] = start server

  • rails c = start console

  • rails g[enerate] = generate

  Some new rake commands:-

  • rake db:forward

  • rake routes CONTROLLER=users
Generators
• All rewritten: http://www.viget.com/extend/rails-3-
  generators-the-old-faithful

• More easily build new templates with Thor: http://
  caffeinedd.com/guides/331-making-generators-for-
  rails-3-with-thor

• RAILS_ROOT/lib/templates override generator
  templates

• Rails::Generators::TestCase for testing generators

• _form partials   and smart labels for form buttons
Extras

• config.filter_parameters << :password
• RAILS_ENV, RAILS_ROOT, etc.
• redirect_to(@user, :notice => ... )
• ‘validates :login, :presence =>
  true, :length => { :minimum =>
  4}, :inclusion => { :in => [1, 2, 3] }’
l18n

• I18n faster
• I18n on any object
• attributes have default translations
• Submit tags label automatically
• labels pass attribute name
Before Upgrading...
    Note: Currently Beta2, so need to be brave/sure/low-impact


You will need/want:-
• www.railsupgradehandbook.com Jeremy McAnally

• http://github.com/rails/rails_upgrade

• RVM or other multi-ruby support

• Good test coverage (without factory_girl/shoulda?)

• Rails 3 hosting

• New git branch?
RVM
• Run any version of Ruby in its own environment

• Rails 3 needs at least 1.8.7 - Serious bugs in 1.9.1,
  recommended version 1.9.2

• RVM lets you find best working one for you

• Installation instructions at:

  • http://gist.github.com/296055

  • http://railscasts.com/episodes/200-rails-3-beta-and-rvm

• no SUDO required
Update Check plugin
• http://github.com/rails/rails_upgrade

• Scan for changes to code, etc.

• Convert most routes automatically

• Create bundler Gemfile

• Back up important files

• Create starter configuration
The Rest of the Process
       www.railsupgradehandbook.com   Jeremy McAnally




 • Regenerate the app

 • Application.rb & environment.rb

 • Check and tidy up routes manually

 • Complete Gemfile manually

 • Make all tests run

 • Other Rails 3 enhancements (can be deferred)

 • Host prepare and deploy (Heroku?)
Help & thanks
•   http://www.railsupgradehandbook.com/ by Jeremy McAnally

•   http://railscasts.com by Ryan Bates

•   http://guides.rails.info/3_0_release_notes.html

•   http://www.railsplugins.org/

•   http://ruby5.envylabs.com/

•   http://blog.envylabs.com/2010/02/rails-3-beautiful-code/ by Greg
    Pollack

•   http://weblog.rubyonrails.org/2010/4/1/rails-3-0-second-beta-release

More Related Content

Rails 3 (beta) Roundup

  • 1. Rails 3 (beta) Roundup April 6, 2010
  • 2. Why Upgrade • Performance tighter & faster codebase, relational optimizations, shorter path to response, better scaling, better use of Rack & Middleware • Security better routing DSL, XSS protection, more powerful controller stack, better use of Rack & Middleware, fixes • Labour-savings easier routing, reliable gem management, easier Ajax, better code reuse, less monkey-patching, better & easier generators • Modernization Rack reliance, later Ruby, plug in new frameworks and components, new standards • Cost saving lower hardware requirements, less Gem maintenance, consistency means easier for developers
  • 3. HTTP://GUIDES.RAILS.INFO/3_0_RELEASE_NOTES.HTML Significant Features • Dependency management with Bundler • More concise router • Chainable database query language • New ActionMailer API • Unobtrusive JavaScript • Better modularity • Improved XSS protection
  • 4. Bundler http://railscasts.com/episodes/201-bundler get used to version juggling for now gem "rails", "3.0.0.beta" • all gems listed in # gem "rails", :git => "git://github.com/rails/ Gemfile rails.git" gem "sqlite3-ruby", :require => "sqlite3" • ‘setup’ gemfile # gem "rspec", :group => :test group :test do gem "webrat" end • ‘install’ gem install bundler bundle setup • ‘pack’ bundle install bundle unlock mate Gemfile bundle install --without=test • deploy app bundle pack # application.rb • unlock to modify require 'rails/all' Bundler.require(:default, Rails.env) if defined?(Bundler) Need version 9+. No config.gem required for Rails 3, although some need it for Rails 2.
  • 5. New Modular Architecture • “Railties framework is now a set of individual Railties, each inheriting from a new class, Rails::Railtie” • Third-party plugins hook into early stages of initialization • Rake tasks and generators part of the frameworks • “In short, Rails frameworks are now plugins to Rails” Action Mailer * Action Pack * Active Record * Active Resource * Active Model * Active Support • And features like ActiveRecord validations and serialization reusable, eg: include ActiveModel::Validations
  • 6. Routing resources :products do   • more concise get :detailed, :on => :member  end   block resources :forums do   DSL collection do   get :sortable   put :sort  end   resources :topics • rack routes end match "/secret" => "info#about", :constraints => { :user_agent => /Firefox/ } constraints :host => /localhost/ do   • constraints match "/secret" => "info#about"   match "/topsecret" => "info#about"   end  match "/hello" => proc { |env| [200, {}, "Hello Rack!"] } • other features root :to => "home#index" match "/about" => "info#about",  :as => :about
  • 7. Controllers • taller stack abstracting rendering, layouts, rack, AbstractController::Base etc ActionController::Metal • enhance by subclassing New relevant layer ActionController::Base Old • middleware layer ApplicationController • ‘respond_with(@post)’ MyController • flash[:notice] & flash[:alert]
  • 8. ActionMailer • like a controller r g mailer UserMailer welcome gives... • email types like actions class UserMailer < ActionMailer::Base def welcome(user, subdomain) @user = user • mail() to send @subdomain = subdomain mail(:from => "admin@testapp.com", :to => @user.email, • no ‘deliver_’ prefix :subject => "Welcome to TestApp") end • mail() do..end for end multipart
  • 9. More ActionMailer class UserMailer < ActionMailer::Base default :from => "admin@testapp.com" def welcome(user, subdomain) @user = user @subdomain = subdomain attachments['test.pdf'] = File.read("# {Rails.root}/public/test.pdf") mail(:to => @user.email, :subject => "Welcome to TestApp") do |format| format.html { render 'other_html_welcome' } format.text { render 'other_text_welcome' } end end end
  • 10. More ActionMailer class UserMailer < ActionMailer::Base default :from => "admin@testapp.com" def welcome(user, subdomain) @user = user @subdomain = subdomain attachments['test.pdf'] = File.read("# {Rails.root}/public/test.pdf") mail(:to => @user.email, :subject => "Welcome to TestApp") do |format| format.html { render 'other_html_welcome' } format.text { render 'other_text_welcome' } end end end
  • 11. Models • New ActiveModel MyClass • Encapsulates ActiveModel::Validations features Serialization ActiveModel::Observing • ‘include’ in non- ActiveModel::Serialization ActiveRecords etc.. • also...
  • 12. Find and Scopes • Relational algebra # Article.find(:all, :order => "published_at desc", :limit => 10) Article.order("published_at desc").limit(10) • chained methods # Article.find(:all, :conditions => ["title = ?", ‘This’], :include => :comments) Article.where("title = ?", • named_scope now ‘This’).includes(:comments) scope # Article.find(:first, :order => "published_at desc") Article.order("published_at").last • conditions now # models/active_record.rb scope :visible, where("hidden != ?", true) where scope :published, lambda { where("published_at <= ?", Time.zone.now) } scope :recent, visible.published.order("published_at desc") • deferred retrieval
  • 13. ActiveRelation Methods • where • limit • select • joins • order • group • offset • having • includes • lock • readonly • from Book.where(:author => "Austen").include(:versions).order(:title).limit(10) Executed only when the data is needed
  • 14. In Views <%= form_for @product do |f| %> • ‘=’ required for all tags <% end %> that output content <%= div_for @product do %> <% end %> including blocks, like <% @comments.each do |c| %> <% end %> ‘form_for’ <% content_for :side do %> <% end %> • ‘-’ no longer required <% cache do %> <% end %> to suppress spaces <!-- products/show.html.erb --> <%= admin_area do %> • write_output_buffer <%= link_to "Edit", edit_product_path(@product) %> | <%= link_to "Destroy", @product, :confirm => "Are you sure?", :method => :delete %> | method in helpers <%= link_to "View All", products_path %> <% end %> # application_helper.rb • no ‘=’ for cache helper def admin_area(&block) content = with_output_buffer(&block) content_tag(:div, content, :class => "admin") end
  • 15. XSS Protection • ‘h’ assumed <!-- views/comments/_comment.html.erb --> <div class="comment"> • new ‘raw’ method to %> <%= strong link_to(comment.name, comment.url) unescape <p><%= comment.content %></p> </div> # rails c • html_safe? and "foo".html_safe? safe = "safe".html_safe safe.html_safe? html_safe method to # application_helper.rb check/make string safe def strong(content) "<strong>#{h(content)}</strong>".html_safe end • ‘html_safe’ must be used on helper output
  • 16. Unobtrusive Javascript <!-- products/index.html.erb --> <% form_tag products_path, :method => :get, :remote => true do • Makes use of ‘data- %> <p> remote’ tag for Ajax forms <%= text_field_tag :search, params[:search] %> <%= submit_tag "Search", :name => nil %> </p> <% end %> • Other Javascript tag <a href="#" id="alert" data-message="Hello UJS!">Click Here</a> ‘data-’ attributes <%= link_to 'Destroy', post, :method => :delete %> supported In rails.js document.observe("dom:loaded", function() { $(document.body).observe("click", function(event) { • http://github.com/rails/ var message = event.element().readAttribute('data-confirm'); if (message) { jquery-ujs } // ... Do a confirm box var element = event.findElement("a[data-remote=true]"); if (element) { • http://github.com/rails/ // ... Do the AJAX call } var element = event.findElement("a[data-method]"); prototype_legacy_helper if (element) { // ... Create a form } });
  • 17. The Commandline • rails s[erver] = start server • rails c = start console • rails g[enerate] = generate Some new rake commands:- • rake db:forward • rake routes CONTROLLER=users
  • 18. Generators • All rewritten: http://www.viget.com/extend/rails-3- generators-the-old-faithful • More easily build new templates with Thor: http:// caffeinedd.com/guides/331-making-generators-for- rails-3-with-thor • RAILS_ROOT/lib/templates override generator templates • Rails::Generators::TestCase for testing generators • _form partials and smart labels for form buttons
  • 19. Extras • config.filter_parameters << :password • RAILS_ENV, RAILS_ROOT, etc. • redirect_to(@user, :notice => ... ) • ‘validates :login, :presence => true, :length => { :minimum => 4}, :inclusion => { :in => [1, 2, 3] }’
  • 20. l18n • I18n faster • I18n on any object • attributes have default translations • Submit tags label automatically • labels pass attribute name
  • 21. Before Upgrading... Note: Currently Beta2, so need to be brave/sure/low-impact You will need/want:- • www.railsupgradehandbook.com Jeremy McAnally • http://github.com/rails/rails_upgrade • RVM or other multi-ruby support • Good test coverage (without factory_girl/shoulda?) • Rails 3 hosting • New git branch?
  • 22. RVM • Run any version of Ruby in its own environment • Rails 3 needs at least 1.8.7 - Serious bugs in 1.9.1, recommended version 1.9.2 • RVM lets you find best working one for you • Installation instructions at: • http://gist.github.com/296055 • http://railscasts.com/episodes/200-rails-3-beta-and-rvm • no SUDO required
  • 23. Update Check plugin • http://github.com/rails/rails_upgrade • Scan for changes to code, etc. • Convert most routes automatically • Create bundler Gemfile • Back up important files • Create starter configuration
  • 24. The Rest of the Process www.railsupgradehandbook.com Jeremy McAnally • Regenerate the app • Application.rb & environment.rb • Check and tidy up routes manually • Complete Gemfile manually • Make all tests run • Other Rails 3 enhancements (can be deferred) • Host prepare and deploy (Heroku?)
  • 25. Help & thanks • http://www.railsupgradehandbook.com/ by Jeremy McAnally • http://railscasts.com by Ryan Bates • http://guides.rails.info/3_0_release_notes.html • http://www.railsplugins.org/ • http://ruby5.envylabs.com/ • http://blog.envylabs.com/2010/02/rails-3-beautiful-code/ by Greg Pollack • http://weblog.rubyonrails.org/2010/4/1/rails-3-0-second-beta-release

Editor's Notes