Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What's New in Rails 4

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.

Ben Hughes

February 08, 2013
Tweet

More Decks by Ben Hughes

Other Decks in Programming

Transcript

  1. 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
  2. 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
  3. THREAD SAFE BY DEFAULT Make sure your code & all

    gems is thread safe! Or disable thread safety (middleware Rack::Lock). Thursday, February 7, 13
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. 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
  10. 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
  11. 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
  12. 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
  13. 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
  14. 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
  15. 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
  16. 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
  17. 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
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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