Pro Yearly is on sale from $80 to $50! »

What's New in Rails 4

92772ff5353c89d9bd10f8e334161e16?s=47 Ben Hughes
February 08, 2013

What's New in Rails 4

I give a run-down of some of the latest features in Rails slated for the 4.0 release, and tips on how to prepare your Rails 3 app for upcoming changes.

92772ff5353c89d9bd10f8e334161e16?s=128

Ben Hughes

February 08, 2013
Tweet

Transcript

  1. WHAT’S NEW IN RAILS 4 Ben Hughes @rubiety http://benhugh.es Thursday,

    February 7, 13
  2. RAILS EVOLUTION Thursday, February 7, 13

  3. RAILS 2: REST ARCHITECTURE Thursday, February 7, 13

  4. RAILS 3: MODULARIZATION ASSET PIPELINE Thursday, February 7, 13

  5. RAILS 4: CLOSET-CLEANING FORWARD REFINEMENT Thursday, February 7, 13

  6. Thursday, February 7, 13

  7. RUBY 1.9.3 REQUIRED Thursday, February 7, 13

  8. STRONG PARAMETERS class PeopleController < ApplicationController def create @person =

    Person.create(params[:person]) end end class Person < ActiveRecord::Base attr_accessible :name, :age end In Rails 3: Thursday, February 7, 13
  9. STRONG PARAMETERS class PeopleController < ApplicationController def create @person =

    Person.create(person_params) end private def person_params params.require(:person).permit(:name, :age) end end Use in Rails 3 Today: https://github.com/rails/strong_parameters In Rails 4: Thursday, February 7, 13
  10. THREAD SAFE BY DEFAULT Make sure your code & all

    gems is thread safe! Or disable thread safety (middleware Rack::Lock). Thursday, February 7, 13
  11. LIVE STREAMING class MyController < ActionController::Base include ActionController::Live def stream

    response.headers['Content-Type'] = 'text/event-stream' 100.times { response.stream.write "hello world\n" sleep 1 } response.stream.close end end Thursday, February 7, 13
  12. LIVE STREAMING CAVEATS • Actions run in separate thread; controller

    action code must be thread save! • Concurrent Ruby Server Required (puma, rainbows!, thin) • Headers must be written before anything else • Streams must be closed http://tenderlovemaking.com/2012/07/30/is-it-live.html Thursday, February 7, 13
  13. TURBOLINKS https://github.com/rails/turbolinks http://railscasts.com/episodes/390-turbolinks Similar to PJAX Use in Rails 3

    Today: gem “turbolinks” // app/assets/javascripts/application.js //= require jquery //= require jquery_ujs //= require turbolinks //= require_tree . Thursday, February 7, 13
  14. BEFORE_FILTER => BEFORE_ACTION Thursday, February 7, 13

  15. POSTGRES ARRAY SUPPORT class AddTagsToArticles < ActiveRecord::Migration def change change_table

    :articles do |t| t.string :tags, array: true end end end article.tags = ['rails'] article.save # UPDATE "articles" SET "tags" = '{"rails"}' # WHERE "articles"."id" = 1 HStore Support New Data Types Support Thursday, February 7, 13
  16. AREL .WHERE.NOT(:A => 1) Article.where.not(title: 'Rails 3') Article.where.not(title: ['Rails 3',

    'Rails 5']) Article.where("title != ?", "Rails 3") Article.where("title NOT IN (?)", ["Rails 3", "Rails 5"]) In Rails 3: In Rails 4: Thursday, February 7, 13
  17. AREL .FIRST / .LAST In Rails 3: Calling .first or

    .last was indeterminate (DB-specific). In Rails 4: Calling .first or .last defaults to using ORDER BY id. Thursday, February 7, 13
  18. AREL .NONE @posts = current_user.visible_posts.where(:name => params[:name]) def visible_posts case

    role if 'Country Manager' Post.where(:country => country) if 'Reviewer' Post.published if 'Bad User' # returning [] instead breaks the previous code; not chainable Post.where("1=0") end end In Rails 3: Thursday, February 7, 13
  19. AREL .NONE @posts = current_user.visible_posts.where(:name => params[:name]) def visible_posts case

    role if 'Country Manager' Post.where(:country => country) if 'Reviewer' Post.published if 'Bad User' # returning [] instead breaks the previous code; not chainable Post.none end end In Rails 4: Thursday, February 7, 13
  20. AREL BANG! METHODS class PeopleController < ApplicationController def index @people

    = People.active @people = @people.where(:first_name => params[:first_name]) if params[:last_name].present? @people = @people.where(:last_name => params[:last_name]) if params[:last_name].present? end end In Rails 3: Thursday, February 7, 13
  21. AREL BANG! METHODS class PeopleController < ApplicationController def index @people

    = People.active @people.where!(:first_name => params[:first_name]) if params[:last_name].present? @people.where!(:last_name => params[:last_name]) if params[:last_name].present? end end In Rails 4: Thursday, February 7, 13
  22. ROUTING CONCERNS Penguin::Application.routes.draw do resources :projects do resources :comments end

    resources :tasks do resources :comments end resources :articles do resources :comments end end In Rails 3: Thursday, February 7, 13
  23. ROUTING CONCERNS In Rails 4: Penguin::Application.routes.draw do concern :commentable do

    resources :comments end resources :projects, concerns: :commentable resources :tasks, concerns: :commentable resources :articles, concerns: :commentable end Use in Rails 3 Today: https://github.com/rails/routing_concerns Thursday, February 7, 13
  24. CACHING GEM EXTRACTIONS: gem “actionpack-page_caching” gem “actionpack-action_caching” Thursday, February 7,

    13
  25. OBSERVERS/SWEEPERS EXTRACTED gem “rails-observers” Thursday, February 7, 13

  26. FRAGMENT CACHE DIGESTS # app/views/todolists/_todolist.html.erb <% cache todolist do %>

    My todolist: <%= todolist.name %> <%= render document.comments %> <% end %> # app/views/comments/_comment.html.erb <% cache comment do %> My comment: <%= comment.body %> <% end %> In Rails 3: Thursday, February 7, 13
  27. FRAGMENT CACHE DIGESTS # app/views/todolists/_todolist.html.erb <% cache [ "v1", todolist

    ] do %> My todolist: <%= todolist.name %> <%= render document.comments %> <% end %> # app/views/comments/_comment.html.erb <% cache [ "v1", comment ] do %> My comment: <%= comment.body %> <% end %> In Rails 3: Thursday, February 7, 13
  28. FRAGMENT CACHE DIGESTS # app/views/todolists/_todolist.html.erb <% cache todolist do %>

    My todolist: <%= todolist.name %> <%= render document.comments %> <% end %> # app/views/comments/_comment.html.erb <% cache comment do %> My comment: <%= comment.body %> <% end %> In Rails 4: Thursday, February 7, 13
  29. NO VENDORED PLUGINS rm -rf vendor/plugins Thursday, February 7, 13

  30. AR SESSION STORE GEM EXTRACTION gem “activerecord-session_store” Thursday, February 7,

    13
  31. ACTIVERESOURCE EXTRACTED gem “activeresource” Thursday, February 7, 13

  32. SPROCKET-POWERD ASSET PIPELINE EXTRACTED gem “sprocket-rails” Differential Pre-compilation (Finally!) Silent

    Logging (replaces need for quiet_assets gem) Thursday, February 7, 13
  33. SCOPES REQUIRE CALLABLES In Rails 4: class Team < ActiveRecord::Base

    scope :active, where(active: true) scope :recent, where(published_at: Time.now - 2.weeks) end class Team < ActiveRecord::Base scope :active, -> { where(active: true) } scope :recent, -> { where(published_at: Time.now - 2.weeks) } end Thursday, February 7, 13
  34. DEPRECATED FINDERS # find_all_by_ Rails 3: Team.find_all_by_name('Justice League') Rails 4:

    Team.where(name: 'Justice League') # find_last_by_ Rails 3: Team.find_last_by_name('Justice League') Rails 4: Team.where(name: 'Justice League').last # find_or_create_by_ Rails 3: Team.find_or_create_by_name('Justice League') Rails 4: Team.where(name: 'Justice League').first_or_create # find_or_initialize_by_ Rails 3: Team.find_or_initialize_by_name('Justice League') Rails 4: Team.where(name: 'Justice League').first_or_initialize # scoped_by_ Rails 3: Team.scoped_by_name('Justice League') Rails 4: Team.where(name: 'Justice League') Thursday, February 7, 13
  35. DEPRECATED HASH FINDERS Rails 3: Team.all(conditions: { name: 'Test' })

    Rails 4: Team.where(name: 'Test') Really like this syntax anyways? Okay then... gem “activerecord-deprecated_finders” Thursday, February 7, 13
  36. PATCH, NOT PUT RFC 5789 technically describes PATCH as a

    partial update, what everyone is using PUT for today. Default for update will now be PATCH. https://github.com/rails/rails/pull/505 Thursday, February 7, 13
  37. PLAY WITH RAILS 4 NOW $ git clone http://github.com/rails/rails.git $

    cd rails && bundle install $ ruby railties/bin/rails new ../try_four --dev $ cd ../try_four Thursday, February 7, 13
  38. RESOURCES • http://blog.remarkablelabs.com/2012/11/rails-4-countdown- to-2013 • https://speakerdeck.com/kvzb/wtf-rails-4 • http://blog.wyeworks.com/2012/10/29/rails-4-in-30-minutes/ • http://edgeguides.rubyonrails.org/4_0_release_notes.html

    • http://afreshcup.com/ Thursday, February 7, 13
  39. THANKS! QUESTIONS? Ben Hughes @rubiety http://benhugh.es Thursday, February 7, 13