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

Rails 4.0

Rails 4.0

Presented at @rubymn and MinneBar 2013.

Derek Rockwell

April 06, 2013
Tweet

Other Decks in Technology

Transcript

  1. Rails 4 Housekeeping ❖ Extractions, standardizing lifecycle, deprecations Performance ❖

    Queueing, caching, Turbolinks, default threadsafe, streaming New features ❖ PATCH, Concerns, ActiveRecord, Model Ruby 1.9.3 (Ruby 2.0.0 preferred) ❖ Nuff’ said {
  2. Extracted to Gem: • Mass Assignment Protection • Observers/Sweepers •

    Sprockets • Dynamic Finders • Page/Action Caching • ActiveResource • ActiveRecord::SessionStore • Performance tests • Hash-based and Dynamic Finders
  3. Version Policy Standardizing 4.0.0 - simple upgrade from 3.2 4.0.x

    - no new deprecations 4.1.0 - new features, removal of deprecations
  4. config.threadsafe! ...redundant, since Rails defaults to be threadsafe in production

    Rails::Plugin ...no more vendor/plugins, use gems or bundler with path/git routes
  5. Match routes Rails 3 match '/lolcat/:id/memeify', to: 'lolcats#memeify' Rails 4

    match '/lolcat/:id/memeify', to: 'lolcats#memeify', via :post post '/lolcat/:id/memeify', to: 'lolcats#memeify' or... via :get via :put via :delete via :all Also... Generates a bunch of routes. Potential XSS risk!
  6. attr_accessible Rails 3 class User < ActiveRecord::Base attr_accessible :username, :password

    end class UsersController < ApplicationController def create @user = User.create! params[:user] redirect_to @user end end
  7. ...to Strong Parameters Rails 4 class User < ActiveRecord::Base end

    class UsersController < ApplicationController def create @user = User.create! user_params redirect_to @user end private def user_params params.require(:user).permit(:username, :password) end end
  8. Scopes Rails 3 class Blog < ActiveRecord::Base scope :recent, where(created_at:,

    2.weeks.ago) end Rails 4 class Blog < ActiveRecord::Base scope :recent, -> {where(created_at:, 2.weeks.ago)} end
  9. ActiveSupport::Queue New Queue Interface: Rails.queue.push Job.new job = Rails.queue.pop job.run

    *Queue interface feature has been pushed back, probably until 4.1
  10. ActiveSupport::Queue Supports many different queue implementations: #new, not yet production

    ready, threaded config.queue = ActiveSupport::Queue.new #new, not yet production ready, synchronous config.queue = ActiveSupport::SynchronousQueue.new config.queue = Resque::Rails::Queue.new config.queue = Sidekiq::Client::Queue.new *Queue interface feature has been pushed back, probably until 4.1
  11. Turbolinks ...frickin’ magic.            user  

           system            total                real  no  turbolinks  11.170000      0.980000    12.460000  (138.656728) yes  turbolinks  10.800000      0.870000    11.670000  (  80.436286)
  12. Turbolinks gem "turbolinks" //= require turbolinks w.addEventListener( "page:load", function(){ w.picturefill();

    }, false ); *onready isn’t relevant when you are updating the page via AJAX
  13. ETags They work by using the HTTP_IF_NONE_MATCH and HTTP_IF_MODIFIED_SINCE headers

    to pass back and forth both a unique content identifier and the timestamp of when the content was last changed. If the browser makes a request where the content identifier (etag) or last modified since timestamp matches the server’s version then the server only needs to send back an empty response with a not modified status. Oh. wat wat
  14. ETags Rails 3 • Create response • MD5 response =>

    ETag • Send response and ETag • If ETag matches cached ETag, load page from client cache
  15. ETags Rails 4 class PostsController < ApplicationController def show @post

    = Posts.find(params[:id]) fresh_when(@post) end end
  16. Cache Digests - Fragments <%= cache ['v1', post] do %>

    <%= post %> <%end%> <%= cache ['v2', post] do %> <%= post %> <%end%> <%= cache ['v3', post] do %> <%= post %> <%end%> <%= cache ['v4', post] do %> <%= post %> <%end%> Rails 3 caches changes in the model, but not the template, versioning tracks changes in the template
  17. Cache Digests - Fragments <%= cache post do %> <%=

    post %> <%end%> Rails 4 caches also tracks changes in the template, removing the need for versioning
  18. ActiveController:Live class MessagesController < ApplicationController include ActionController::Live def events response.headers["Content-Type"]

    = "text/event-stream" redis = Redis.new redis.subscribe('messages.create') do |on| on.message do |event, data| response.stream.write("data: #{data}\n\n") end end redis.quit response.stream.close end end def create attributes = params.require(:message).permit(:content, :name) @message = Message.create!(attributes) $redis.publish('messages.create', @message.to_json) end
  19. ActiveController:Live $(document).ready(initialize); function initialize() { var source = new EventSource('/messages/events');

    source.addEventListener('message', update); }; function update(event) { var item = $('<li>').text(event.data); $('#items').append(item); };
  20. ActiveController:Live Caveats: ✤ Code must be thread-safe (Rails4 is thread-safe

    by default) ✤ Write thread-safe code (thread-safe gem, locks) ✤ Web server must support concurrency (e.g. Thin or Puma) in lieu of multi-process servers ✤ Don’t forget to write headers first and close your stream
  21. Model#none Rails 3 def show_posts if current_user.banned? [] else Post.where(published:

    true) end end if show_posts.any? show_posts.recent else [] end Rails 4 def show_posts if current_user.banned? Post.none else Post.where(published: true) end end show_posts.recent
  22. Relation#not Rails 3 if @author Post.where('author != ?', @author) else

    Post.where('author is not null') end Rails 4 Post.where.not(author: @author)
  23. Concerns Rails3 resources :posts do resources :comments resources :categories resources

    :tags end resources :articles do resources :comments resources :categories resources :tags end Rails4 concern :sociable do resources :comments resources :categories resources :tags end resources :posts, concerns: :sociable resources :articles, concerns: :sociable Extract common model behavior to concerns via new concerns directory
  24. Custom Flash Types class ApplicationController < ActionController::Base add_flash_types :emergency end

    redirect_to @user, emergency: "#openbar" <div class="emergency"> <p><%= emergency %></p> </div>
  25. ActiveModel::Model class Contact include ActiveModel::Model attr_accessor :name, :email, :message validates

    :name, presence: true validates :email, presence: true validates :message, presence: true, length: { maximum: 300 } end def create @contact = Contact.new(params[:contact]) if @contact.valid? ContactMailer.new_contact(@contact).deliver redirect_to root_path else render :new end end
  26. HTML5 Helpers <%= f.date_field :date %> <%= f.month_field :month %>

    <%= f.week_field :week %> <%= f.day_field :day %> <%= f.color_field :color %> <%= f.time_field :time %>
  27. Collection Helpers Rails 3 #create a select box for all

    post authors collection_select(:post, :user_id, User.all, :id, :name) Rails 4 collection_radio_buttons(:post, :user_id, User.all, :id, :name) collection_check_boxes(:post, :user_id, User.all, :id, :name)
  28. index.html No more deleting index.html, it is now a dynamic

    route! Add a root entry in routes.rb to override new welcome controller
  29. Filters *_filter actions have been renamed to *_action Rails3 before_filter

    :set_something, except [:delete] Rails4 before_action :set_something, except [:delete] ...backwards compatible
  30. ruby @posts Ruby template handler def index @posts = Posts.all

    respond_to do |format| format.html format.json { render json: @posts } end end #views/posts/index.json.ruby posts_hashes = @owners.map do |owner| { name: owner.author, url: post_url(post) } end posts_hashes.to_json
  31. Installing $ rvm use [email protected]_myapp --create $ gem install rails

    --version 4.0.0.beta1 $ rails new myapp Fair number of major gems have rails4 branches so you can start toying with beta1 today
  32. @derekrockwell Rails.MN Community teaching Ruby on Rails to beginners; sponsored

    by CoCo + Google for Entrepreneurs meeting the second Monday of each month