what’s new in rails 5.0?

50
WHAT’S NEW IN RAILS 5 WHAT’S NEW IN RAILS 5 ANDREW WHITE, CTO ANDREW WHITE, CTO UNBOXED CONSULTING UNBOXED CONSULTING

Upload: unboxed

Post on 19-Jan-2017

1.058 views

Category:

Technology


0 download

TRANSCRIPT

WHAT’S NEW IN RAILS 5WHAT’S NEW IN RAILS 5ANDREW WHITE, CTOANDREW WHITE, CTO

UNBOXED CONSULTINGUNBOXED CONSULTING

WHO AM I?WHO AM I?GitHub: @pixeltrix

Twitter: @pixeltrix

Contributor since 2007

Committer since 2010

Core Team member since 2012

RAILS TIMELINERAILS TIMELINERails 1.0: December 2005

Rails 2.0: December 2007

Rails 3.0: August 2010

Rails 4.0: June 2013

Rails 5.0: Autumn 2015

DON’T PANIC!DON’T PANIC!… it’s not going to be like Rails 3.0

ACTION CABLEACTION CABLEhttps://github.com/rails/actioncable

WHAT IS IT?WHAT IS IT?

ACTION CABLE: TECHNOLOGY STACKACTION CABLE: TECHNOLOGY STACK

Faye WebSocket for Ruby

Event Machine

Celluloid

Redis

https://github.com/faye/faye-websocket-ruby

https://github.com/eventmachine/eventmachine

https://github.com/celluloid/celluloid

http://redis.io

ACTION CABLE: TERMINOLOGYACTION CABLE: TERMINOLOGY

Channel:- similar to a controller in MVC

Consumer:- WebSocket client, typically a browser

Subscriber:- a consumer that’s connected to a channel

Subscription:- a connection between the consumer and the channel

ACTION CABLE: PRESENCE EXAMPLEACTION CABLE: PRESENCE EXAMPLE

Create a connection class

Create an application channel class

Connect in the browser

Create a channel class

Create a subscription class

ACTION CABLE: CONNECTION CLASSACTION CABLE: CONNECTION CLASS# app/channels/application_cable/connection.rbmodule ApplicationCable class Connection < ActionCable::Connection::Base identified_by :current_user

def connect self.current_user = find_verified_user end

protected def find_verified_user if current_user = User.find(cookies.signed[:user_id]) current_user else reject_unauthorized_connection end end endend

ACTION CABLE: APPLICATION CHANNEL CLASSACTION CABLE: APPLICATION CHANNEL CLASS# app/channels/application_cable/channel.rbmodule ApplicationCable class Channel < ActionCable::Channel::Base # shared logic between channels endend

ACTION CABLE: CONSUMER CREATIONACTION CABLE: CONSUMER CREATION# app/assets/javascripts/application_cable.coffee#= require cable

@App = {}App.cable = Cable.createConsumer "ws://cable.example.com"

ACTION CABLE: CHANNEL CLASSACTION CABLE: CHANNEL CLASS# app/channels/appearance_channel.rbclass AppearanceChannel < ApplicationCable::Channel def subscribed current_user.appear end

def unsubscribed current_user.disappear end

def appear(data) current_user.appear on: data['appearing_on'] end

def away current_user.away endend

ACTION CABLE: SUBSCRIPTION CLASSACTION CABLE: SUBSCRIPTION CLASS# app/assets/javascripts/cable/subscriptions/appearance.coffeeApp.appearance = App.cable.subscriptions.create "AppearanceChannel", connected: -> # Called once the subscription has been successfully completed

appear: -> @perform 'appear', appearing_on: @appearingOn()

away: -> @perform 'away'

appearingOn: -> $('main').data 'appearing-on'

$(document).on 'page:change', -> App.appearance.appear()

$(document).on 'click', '[data-behavior~=appear_away]', -> App.appearance.away() false

ACTION CABLE: ROUGH EDGESACTION CABLE: ROUGH EDGES

Redis required for pubsub

Have to run a second server

Two concurrency models

FURTHER EXAMPLESFURTHER EXAMPLEShttp://github.com/rails/actioncable-examples

TURBOLINKS 3TURBOLINKS 3https://github.com/rails/turbolinks

TURBOLINKS 3: NEW FEATURESTURBOLINKS 3: NEW FEATURESNew data attributes:data-turbolinks-permanent

data-turbolinks-temporary

Redirecting uses Turbolinks for XHR and non-GET requests

Progress bar enabled by default

TURBOLINKS 3: PERSISTENT ELEMENTSTURBOLINKS 3: PERSISTENT ELEMENTSdata-turbolinks-permanent

Elements transferred from page to page

Maintains state - ideal for sidebar navigation

Elements must have a unique id attribute

<div id="sidebar" data-turbolinks-permanent=""> Never changes after initial load.</div>

TURBOLINKS 3: PARTIAL REPLACEMENTTURBOLINKS 3: PARTIAL REPLACEMENTReplacement based on id or id and data attributes

Match on id prefixes using colon, e.g:

<div id="flash" data-turbolinks-temporary=""> You have 2 comments.</div><ul id="comments"> <li id="comments:1">Hello, World!</li> <li id="comments:2">Goodbye!</li></ul>

// Will change #flash, #comments, #comments:1, #comments:2Turbolinks.visit(url, { change: ['comments'] });

// Will change #flash, #comments:1Turbolinks.visit(url, { change: ['comments:1'] });

TURBOLINKS 3: PARTIAL REPLACEMENTTURBOLINKS 3: PARTIAL REPLACEMENTAlso available server-side with redirect_to or render

Replacement based on id or id and data attributes

Use one of change, keep or change options, e.g:

class CommentsController < ActionController::Base def create @comment = Comment.new(comment_params)

if @comment.save redirect_to comments_url, change: 'comments' else render :new, change: :new_comment end endend

TURBOLINKS 3: PARTIAL REPLACEMENTTURBOLINKS 3: PARTIAL REPLACEMENTBehaviour of render and redirect_to options:

# Refresh any `data-turbolinks-temporary` nodes and# nodes with `id` matching `new_comment`.render view, change: 'new_comment'

# Refresh any `data-turbolinks-temporary` nodes and nodes# with `id` not matching `something` and `something:*`.render view, keep: 'something'

# Replace the entire `body` of the document,# including `data-turbolinks-permanent` nodes.render view, flush: true

GIVE IT A TRY…GIVE IT A TRY…

SPROCKETS 4SPROCKETS 4https://github.com/rails/sprockets

SPROCKETS 4: CHANGESSPROCKETS 4: CHANGESNew home – now a Rails organisation project

Source maps

ES6 support via

Many thanks to

Babel

Richard Schneeman

RAILS 5RAILS 5https://github.com/rails/rails

UNDER THE HOODUNDER THE HOOD

RAILS 5: UNDER THE HOODRAILS 5: UNDER THE HOODRuby 2.2 required

Better performanceBetter garbage collectionBetter profiling tools

Focus on performance

Focus on memory usage

https://github.com/rails/rails/pull/21100https://github.com/rails/rails/pull/21411

https://github.com/rails/rails/pull/21057

CLEANING HOUSECLEANING HOUSE

RAILS 5: CLEANING HOUSERAILS 5: CLEANING HOUSEXML support extracted to gems

Action Mailer*_path helpersdeliver and deliver!

Action PackDOM Assertions:only_path option in *_path helpersstring controller and action keys:to without controller#action:to with a symbol

RAILS 5: CLEANING HOUSERAILS 5: CLEANING HOUSEActive Modelreset_[attribute] and reset_changes

Action RecordBoolean semantics more aligned with RubyTransaction callbacks no longer swallow errorssanitize_sql_hash_for_conditions

Default timestamps columns to null: falseserialized_attributes

Automatic counter caches on has_many :through

RAILS 5: CLEANING HOUSERAILS 5: CLEANING HOUSEActive Support

Default test order is now randomBigDecimal is always encoded as a stringsilence_stderr, silence_stream, capture and quietly

Railtiesrake test:all and rake test:all:db

RAILS 5: CLEANING HOUSERAILS 5: CLEANING HOUSENew deprecations in Active Record for 5.1

Conditions with delete_all and destroy_allActiveRecord::Relation#uniq

Passing a class to whereColumns of type :time will become timezone aware

EVOLUTION, NOTEVOLUTION, NOTREVOLUTIONREVOLUTION

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONActive Record callbacks can now be halted explicitlythrow :abort

New apps get new behaviourUpgraded apps get a deprecation warning

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONActionController::Parameters no longer inherits from Hash

Composition over inheritance FTW!No more accidentally calling Enumerable methodsNo more accidentally returning a HashNo more accidentally losing permitted? status

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONvalidates_acceptance_of accepts 1 or true

Reversible syntax for change_column_default

# user.rbclass User < ActiveRecord::Base attr_accessor :terms_and_conditions validates_acceptance_of :terms_and_conditionsend

change_column_default(:posts, :state, from: nil, to: "draft")

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONAccept a collection in fresh_when and stale?

expands to:

def index @article = Article.all fresh_when(@articles)end

def index @article = Article.all fresh_when(etag: @articles, last_modified: @articles.maximum(:updated_at))end

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONAdd a http_cache_forever to never expire content

Remove restrictions on partial names

def hello_world http_cache_forever do render text: "Hello, World!" endend

render partial: '! '

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONBoot rails s in development with caching enabled

Non-request context rendering

rails s --dev-caching

ApplicationController.render template: 'foo/bar'

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONBuilt-in support for generating token attributes

Raw model validation errors

class User < ActiveRecord::Base has_secure_tokenend

class User < ActiveRecord::Base validates :name, presence: trueend

user = User.new; user.valid?; user.errors.details=> { name: [{ error: :blank }] }

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONweekend? query method for date and time

next_weekday for next working day

prev_weekday for previous working day

Date.current.weekend?=> false

Date.current.end_of_week.next_weekday=> Mon, 21 Sep 2015

Date.current.beginning_of_week.prev_weekday=> Fri, 11 Sep 2015

RAILS 5: EVOLUTION, NOT REVOLUTIONRAILS 5: EVOLUTION, NOT REVOLUTIONInteger#positive? and Integer#negative?

Built-in support for method.source_code

rails is now the command hub, e.g:

>> Object.new.method(:blank?).source_code def blank? respond_to?(:empty?) ? !!empty? : !self end

rails db:migrate

RAILS APIRAILS APIIt’s coming home, it’s coming home …

RAILS 5: API ONLY APPLICATIONSRAILS 5: API ONLY APPLICATIONSrails new my_api --api

Limited middleware stack

ApplicationController < ActionController::API

Still has essentials like CSRF and HTTP caching

By default uses Active Model Serializers for output

INTEGRATION TESTSINTEGRATION TESTSIntroduced in Rails 1.1

Confusion between controller and integration tests

Controller tests to become integration tests (TBC)

Performance improvements means no cost

Assertions for assigns and rendered templates removed

HOW TO PREPARE?HOW TO PREPARE?Upgrade to Ruby 2.2.3

Upgrade to Rails 4.2.4

Remove legacy gems

Audit dependencies

SUPPORT POLICY: BUG FIXESSUPPORT POLICY: BUG FIXESCurrent minor release

Previous minor release

Currently: 4.1 & 4.2

Will be: 4.2 & 5.0

SUPPORT POLICY: SECURITY UPDATESSUPPORT POLICY: SECURITY UPDATESBug fix releases

Last minor of the previous major

Currently: 3.2, 4.1 & 4.2

Will be: 4.2 & 5.0

Q & AQ & A