Rails 5
What’s in it for
me?
@_cha1tanya
@BigBinary
@Srijan
Overview of
Rails 5
Rails.5.started
_on?
Nov, 2014
9359+ Commits
Beta 3
RC 1 coming
soon
Lots of new
features
Bug fixes
Improvements
DHH Features
Major
features
Ruby 2.2.2+
Rails 5 will require that your apps runs on
Ruby 2.2.2 or latest.
Symbol GC
Incremental GC
Chance to cleanup
Rails internals
Keyword arguments
Rails code can use keyword arguments
internally as now it only supports Ruby 2.2.2 +
Module#prepend
Action Cable
DHH talking about Action Cable
https://www.youtube.com/watch?
v=n0WUjGkDFS0
Full Stack
It has both Ruby side as well as JavaScript
side.
Pub/Sub
Seamless
integration with
other parts
module ApplicationCable
class Connection < ActionCable::Connection::Base
identified_by :current_user
def connect
self.current_user = find_verified_user
end
protected
def find_verified_user
id = cookies.signed[:user_id]
if current_user = User.find_by(id: id)
current_user
else
reject_unauthorized_connection
end
end
end
end
Ruby side
Initially it was started with hard dependency on event
machine.
It was later dropped in
https://github.com/rails/rails/commit/74497eabd52f2f9f8c
383808b11286283046c2b2.
Now Action Cable does not have hard dependency on
Event machine
These are the 3 dependencies of Action
Cable on Ruby side:
websocket-driver
nio4r
concurrent-ruby
Adapters
Inline
Async
Good for development and test mode.
Evented Redis
Non-Evented Redis
Postgresql
For production mode.
Rendering a
template
outside of
controller
ActionController::Renderer.render
Basecamp 3
API only apps
What is an API
only app
Twitter API
Github API
Supplementary APIs where apps are still
traditional web apps
Proliferation of
client side
frameworks
Rails as a Back
End
Which results into using Rails only as back
end app.
No HTML, only
JSON!
Slim version of
Rails
No view layer
Limited set of
middlewares
JBuilder
ActiveModel::Serial
izer
These can be used with API only apps to
generate JSON
Still Rails!
(But for API)
Create new Rails API only app
with
rails new api_app --api
Convert existing app to API only app
config.api_only = true
development
Puma
Puma is default web server now
config/puma.rb
Newly created Rails 5 apps will come with a
config/puma.rb by default.
New Welcome
page
`rails` CLI
rake db:migrate
rails server
Why some rake and
some rails?
In Rails 5, just use `rails`
rails db:migrate
rails server
rails assets:precompile
One `rails`
command to bind
them all!
Rake Proxy
rake db:migrate #works
rails restart
Ability to restart Rails app in development.
https://github.com/rails/rails/issues/18876
tmp/restart.txt
Similar to how passenger restarts app by touching
tmp/restart.txt
Works with Pow,
Puma
rails
dev:cache
Caching in
development mode
In previous Rails versions, caching does not
work automatically in development. Now it
will work in Rails 5.
Toggles caching
in development
Also restarts app
Filtering
routes
https://github.com/rails/rails/issues/18902
Ability to filter routes.
Have thousands of
routes?
Filtering is
easier now
rails routes -c users
rails routes -c admin/users
rails routes -c PostsController
rails routes -g PATCH
rails routes -g admin
Evented File
system monitor
Reloading in
development
Rails reloads all code in development when something
changes. For that it has to do a complete walkthrough
of all files.
Check something has
changed or not
config.file_watcher
gem ‘listen’
test
Test Runner
Rails 5 has added Rspec like test runner
http://blog.bigbinary.com/2016/01/03/test-
runner-in-rails-5.html
bin/rails test
Running a single test by line number
$ bin/rails test test/models/user_test.rb:27
$ bin/rails test test/models test/jobs
Improved failure
message
$ bin/rails t
Run options: --seed 51858
# Running:
.F
Failure:
PostsControllerTest#test_should_get_new:
Expected response to be a <success>, but was a <302>
redirect to <http://test.host/posts>
bin/rails test test/controllers/posts_controller_test.rb:15
Failing fast
$ bin/rails t -f
Run options: -f --seed 59599
# Running:
..F
Failure:
PostsControllerTest#test_should_get_new:
Expected response to be a <success>, but was a <302> redirect to
<http://test.host/posts>
bin/rails test test/controllers/posts_controller_test.rb:15
Interrupted. Exiting...
Finished in 0.179125s, 16.7481 runs/s, 22.3308 assertions/s.
3 runs, 4 assertions, 1 failures, 0 errors, 0 skips
Backtrace
See complete backtrace with -b switch
$ bin/rails t -b
Error:
PostsControllerTest#test_should_create_post:
NameError: undefined local variable or method `boom' for
#<PostsController:0x007fc53c4eb868>
/rails-5-test-runner-app/app/controllers/posts_controller.rb:29:in
`create'
/sources/rails/actionpack/lib/action_controller/metal/basic_implicit_render.rb
:4:in `send_action'
/sources/rails/actionpack/lib/abstract_controller/base.rb:183:in
`process_action'
/sources/rails/actionpack/lib/action_controller/metal/rendering.rb:30:in
`process_action'
/sources/rails/actionpack/lib/abstract_controller/callbacks.rb:20:in
`block in process_action'
/sources/rails/activesupport/lib/active_support/callbacks.rb:126:in `call'
.....
/sources/rails/activesupport/lib/active_support/testing/assertions.rb:71:in
`assert_difference'
/rails-5-test-runner-app/test/controllers/posts_controller_test.rb:19:in
`block in <class:PostsControllerTest>'
Colored output
Controller
tests
assigns
assert_template
assigns
assert_template
Why?
gem ‘action-controller_testing’
Controller tests
are integration
tests
def test_index
get :index
assert_response :success
end
Example of changed controller test.
def test_index
get posts_url
assert_response :success
end
https://github.com/rails/rails/issues/22076
ActionController::TestCase
In Rails 4.x this was the superclass for all controller
tests.
ActionDispatch::IntegrationTest
Now it is this one. Also a lot of effort has gone into
making these tests faster.
More focus on
integration
testing
caching
http_cache_fore
ver
def index
http_cache_forever do
render ‘index’
end
end
Use it with
caution!
It will literally set the cache control headers
for ‘forever’. Make sure that you are using it
with static content only.
Collection
Caching
@users = User.where(city: 'Pune')
No record is deleted.
No record is added.
Caching of
collections
ActiveRecord::Relation#cache_key
@users.cache_key
=> "users/query-67ed32b36805123"
cache(@users) do
………
end
Limitations
Doesn’t work well with limits and groups.
Partials
caching
# index.html.erb
<%= render partial: 'todo',
collection: @todos %>
# _todo.html.erb
<% cache todo do %>
<%= todo.name %>
<% end %>
multi_fetch_fragment
s gem
Folded in Rails 5
Just pass `cached: true` and Rails will fetch all caches
at once.
# index.html.erb
<%= render partial: 'todo',
collection: @todos,
cached: true %>
# _todo.html.erb
<% cache todo do %>
<%= todo.name %>
<% end %>
Caching Action
Mailer views
Active
Record
ApplicationReco
rd
ApplicationRecord is a new superclass for all app models,
analogous to app controllers subclassing ApplicationController
instead of ActionController::Base. This gives apps a single spot to
configure app-wide model behavior
class Post < ActiveRecord::Base
end
class Post < ApplicationRecord
end
#or
Added the #or method on ActiveRecord::Relation,
allowing use of the OR operator to combine WHERE or
HAVING clauses
Post.where('id = 1').or(Post.where('id = 2'))
# => SELECT * FROM posts WHERE (id = 1) OR
(id = 2)
has_secure_toke
n
Added ActiveRecord::SecureToken in order to
encapsulate generation of unique tokens for
attributes in a model using SecureRandom
https://github.com/rails/rails/pull/18217
class User < ApplicationRecord
has_secure_token
end
>> user = User.new
>> user.save
=> true
>> user.token
=> 'qjCbex522DfVEVd5ysUWppWQ'
URL safe
Fixed length strings
Base 58 encoding
Regenerating also
possible
>> user = User.first
=> <User id: 11, name: 'John', email: 'john@example.com',
token: "jRMcN645BQyDr67yHR3qjsJF",
token: "qjCbex522DfVEVd5ysUWppWQ">
>> user.token
=> "qjCbex522DfVEVd5ysUWppWQ"
>> user.regenerate_token
=> true
>> user.token
=> "tYYVjnCEd1LAXvmLCyyQFzbm"
Versioned
migrations
Backward
compatibility
But API must change
For eg. in Rails 4.x
t.timestamps null: false
But in Rails 5, there is no `null: false` still it adds
`NULL` constraint when the migration is run in Rails 5.
t.timestamps # Rails 5
Compatibility Layer
ActiveRecord::Migration
[5.0]
Superclass of migrations in Rails 5. Tells Rails for which
version this migration was generated.
Active
Support
Improvements to
Date/Time
next_day/prev_day
Time.current
=> Fri, 12 Feb 2016 08:53:31 UTC +00:00
Time.current.next_day
=> Sat, 13 Feb 2016 08:53:31 UTC +00:00
Time.current.prev_day
=> Thu, 11 Feb 2016 08:53:31 UTC +00:00
next week with same
time
Time.current
=> Fri, 12 Feb 2016 09:15:10 UTC +00:00
Time.current.next_week
=> Mon, 15 Feb 2016 00:00:00 UTC +00:00
Time.current.next_week(same_time: true)
=> Mon, 15 Feb 2016 09:15:20 UTC +00:00
on_weekend?
Time.current
=> Fri, 12 Feb 2016 09:47:40 UTC +00:00
Time.current.on_weekend?
=> false
Time.current.tomorrow
=> Sat, 13 Feb 2016 09:48:47 UTC +00:00
Time.current.tomorrow.on_weekend?
=> tru
on_weekday?
Time.current
=> Fri, 12 Feb 2016 09:47:40 UTC +00:00
Time.current.on_weekday?
=> true
Time.current.tomorrow
=> Sat, 13 Feb 2016 09:48:47 UTC +00:00
Time.current.tomorrow.on_weekday?
=> false
Time.current
=> Fri, 12 Feb 2016 09:47:40 UTC +00:00
Time.current.next_weekday
=> Mon, 15 Feb 2016 09:55:14 UTC +00:00
Time.current.prev_weekday
=> Thu, 11 Feb 2016 09:55:33 UTC +00:00
Enumerable#pluc
k
users = [{id: 1, name: 'Max'},
{id: 2, name: 'Mark'},
{id: 3, name: 'Jen'}]
users.pluck(:name)
=> ["Max", "Mark", "Jen"]
users = [{id: 1, name: 'Max'},
{id: 2, name: 'Mark'},
{id: 3, name: 'Jen'}]
users.pluck(:id, :name)
=> [[1, "Max"], [2, "Mark"],
[3, "Jen"]]
Improvement to
Active Record’s
pluck
# In Rails 4.x
users = User.all
SELECT `users`.* FROM `users`
users.pluck(:id, :name)
# SELECT "users"."id", "users"."name"
FROM “users"
=> [[1, "Max"], [2, "Mark"],
[3, "George"]]
# In Rails 5
users = User.all
SELECT `users`.* FROM `users`
users.pluck(:id, :name)
=> [[1, "Max"], [2, "Mark"],
[3, "George"]]
Enumerable#withou
t
vehicles = ['Car', 'Bike', 'Truck',
'Bus']
vehicles.without("Car", "Bike")
=> ["Truck", "Bus"]
vehicles = {car: 'Hyundai', bike:
'Honda', bus: 'Mercedes', truck:
'Tata'}
vehicles.without(:bike, :bus)
=> {:car=>"Hyundai", :truck=>"Tata"}
Halting
callback chain
Changed the way in which callback chains can be halted. The
preferred method to halt a callback chain from now on is to
explicitly throw(:abort).
https://github.com/rails/rails/pull/17227
return false from
one of the `before`
callbacks
Stop entire callback
chain
Rails 5 no longer
has this side
effect!
throw(:abort)
Explicitly throw(:abort) to stop it.
While upgrading, it
will still halt
For older apps getting upgraded to Rails 5, the
callback will still halt with returning false, as this is a
breaking change.
ActiveSupport.halt_callback_chains_on_return_false
Once you are ready, toggle this flag and it will use new behaviour of throw.
Performance
https://github.com/rails/rails/pul
l/21057
https://github.com/rails/rails/pul
l/18643
https://github.com/rails/rails/pul
l/21411
https://github.com/rails/rails/pul
l/21155
https://github.com/rails/rails/pul
l/20946
And more…
Attributes
API
Sprockets
3/4
Turbolinks
5
What’s
next?
If you are new to Rails, check out the Rails Doctrine to
understand the philosophy behind Rails.
rubyonrails.org/doctr
ine/
5.0.0.RC1
weblog.rubyonrails
.org
@rails
github.com/rails/r
ails
This week in
Rails
rails-
weekly.goodbits.io
blog.bigbinary.com/categori
es/Rails%205
Try RC
Report bugs
Fix bugs!
Let’s make
Rails better
Thank you!
@_cha1tanya
@BigBinary
@Srijan

[Srijan Wednesday Webinar] Rails 5: What's in It for Me?

Editor's Notes

  • #6 https://github.com/rails/rails/commit/f25ad07f5ade46eb978fa8265
  • #8 http://weblog.rubyonrails.org/2016/2/27/Rails-5-0-beta3/ http://weblog.rubyonrails.org/2016/2/2/Rails-5-0-beta2/ http://weblog.rubyonrails.org/2015/12/18/Rails-5-0-beta1/
  • #9 Pending issues for RC 1 - https://github.com/rails/rails/milestones/5.0.0
  • #14 These are the features proposed by DHH for Rails 5. DHH is creator of Ruby on Rails and he is still passionately involved in Rails development after more than 10 years. Complete list - https://github.com/rails/rails/issues?q=milestone%3A5.0.0+author%3Adhh+is%3Aclosed
  • #16 Rails 5 will require that your apps runs on Ruby 2.2.2 or latest.
  • #17 http://www.sitepoint.com/symbol-gc-ruby-2-2/ https://bugs.ruby-lang.org/issues/9634
  • #18 https://engineering.heroku.com/blogs/2015-02-04-incremental-gc/
  • #20 Rails code can use keyword arguments internally as now it only supports Ruby 2.2.2 +
  • #21 http://www.justinweiss.com/articles/rails-5-module-number-prepend-and-the-end-of-alias-method-chain/
  • #22 DHH talking about Action Cable https://www.youtube.com/watch?v=n0WUjGkDFS0
  • #23 It has both Ruby side as well as JavaScript side.
  • #24 Based on PUB/SUB pattern. http://redis.io/topics/pubsub
  • #25 Works well with other parts of Rails stack like Active Record, Active Job
  • #26 An example showing how you can use Active Record, cookies etc with Action Cable
  • #27 Initially it was started with hard dependency on event machine. It was later dropped in https://github.com/rails/rails/commit/74497eabd52f2f9f8c383808b11286283046c2b2. Now Action Cable does not have hard dependency on Event machine
  • #28 These are the 3 dependencies of Action Cable on Ruby side.
  • #30 Good for development and test mode.
  • #31 For production mode.
  • #32 https://github.com/rails/rails/issues/18409
  • #38 Supplementary APIs where apps are still traditional web apps
  • #40 Growing tendency of using client side frameworks
  • #41 Which results into using Rails only as back end app.
  • #45 http://edgeguides.rubyonrails.org/api_app.html#choosing-middleware
  • #46 These can be used with API only apps to generate JSON
  • #47 http://edgeguides.rubyonrails.org/api_app.html#why-use-rails-for-json-apis-questionmark
  • #48 Create new Rails API only app
  • #49 Convert existing app to API only app. You will also have to do some more stuff.
  • #50 Things improved in development mode in Rails 5
  • #51 Puma is default web server now
  • #52 Newly created Rails 5 apps will come with a config/puma.rb by default.
  • #53 Rails 5 got a new shiny welcome page.
  • #54 In Rails 4.x
  • #55 In Rails 5 :)
  • #56 https://github.com/rails/rails/issues/18878
  • #57 Sometimes rake
  • #58 sometimes rails?
  • #59 Confusing for newcomers
  • #60 In Rails 5, just use `rails`
  • #64 `rake` still works using a proxy.
  • #65 this will still work
  • #66 Ability to restart Rails app in development. https://github.com/rails/rails/issues/18876
  • #67 Similar to how passenger restarts app by touching tmp/restart.txt
  • #68 Currently works with Puma and Pow only.
  • #69 Ability to use caching in development https://github.com/rails/rails/issues/18875
  • #70 In previous Rails versions, caching does not work automatically in development. now it will work in Rails 5.
  • #73 https://github.com/rails/rails/issues/18902 Ability to filter routes.
  • #81 http://weblog.rubyonrails.org/2015/11/11/snappier-development-mode-in-rails-5/
  • #82 Rails reloads all code in development when something changes. For that it has to do a complete walkthrough of all files.
  • #84 Now it doesn’t have to do it because of a evented file system monitor.
  • #85 It is powered by listen gem internally.
  • #86 Changes in test mode
  • #87 Rails 5 has added Rspec like test runner http://blog.bigbinary.com/2016/01/03/test-runner-in-rails-5.html
  • #89 Running a single test by line number
  • #92 See the command which can be run as test for failed tests
  • #94 Fail fast with -f switch
  • #96 See complete backtrace with -b switch
  • #98 Can see coloured output now for our tests by default.
  • #99 Changes to controller tests in Rails 5.
  • #100 We used to use them in our tests.
  • #101 Deprecated in Rails 5. https://github.com/rails/rails/issues/18950
  • #102 https://github.com/rails/rails/issues/18950
  • #103 Use this while upgrading old apps.
  • #104 https://github.com/rails/rails/issues/22496
  • #106 Example of changed controller test. https://github.com/rails/rails/issues/22076
  • #107 In Rails 4.x this was the superclass for all controller tests.
  • #108 Now it is this one. Also a lot of effort has gone into making these tests faster. Action Controller tests may be deprecated and turned into a gem in Rails 5.1.
  • #109 From Rails 5 onwards more focus is on doing integration testing.
  • #110 changes to caching in Rails 5
  • #111 https://github.com/rails/rails/issues/18192
  • #112 https://github.com/rails/rails/pull/18394
  • #113 It will literally set the cache control headers for forever. Make sure that you are using it with static content only.
  • #116 This result does not change unless something is added or deleted.
  • #117 Rails 5 allows caching of collections
  • #118 https://github.com/rails/rails/pull/20884
  • #121 Doesn’t work well with limits and groups.
  • #122 https://github.com/rails/rails/issues/18900
  • #124 https://github.com/rails/rails/pull/18948
  • #126 Just pass `cached: true` and Rails will fetch all caches at once.
  • #127 https://github.com/rails/rails/pull/22825
  • #128 Changes to Active Record in Rails 5
  • #129 ApplicationRecord is a new superclass for all app models, analogous to app controllers subclassing ApplicationController instead of ActionController::Base. This gives apps a single spot to configure app-wide model behavior
  • #131 in Rails 5 https://github.com/rails/rails/pull/22567
  • #132 Added the #or method on ActiveRecord::Relation, allowing use of the OR operator to combine WHERE or HAVING clauses https://github.com/rails/rails/commit/b0b37942d729b6bdcd2e3178eda7fa1de203b3d0
  • #134 Added ActiveRecord::SecureToken in order to encapsulate generation of unique tokens for attributes in a model using SecureRandom https://github.com/rails/rails/pull/18217
  • #137 tokes are url safe
  • #138 and fixed length
  • #142 http://blog.bigbinary.com/2016/03/01/migrations-are-versioned-in-rails-5.html
  • #143 Migrations must be backward compatible across major Rails versions
  • #144 But migrations API must change in major version too.
  • #145 For eg. in Rails 4.x
  • #146 But in Rails 5, there is no `null: false` still it adds `NULL` constraint when the migration is run in Rails 5.
  • #147 So a compatibility layer is introduced for older migrations
  • #148 Superclass of migrations in Rails 5. Tells Rails for which version this migration was generated.
  • #149 Changes to Active Support
  • #150 http://blog.bigbinary.com/2016/02/17/active-support-improvements-in-Rails-5.html
  • #163 It also makes Active Record’s pluck perform better.
  • #169 Changed the way in which callback chains can be halted. The preferred method to halt a callback chain from now on is to explicitly throw(:abort). https://github.com/rails/rails/pull/17227
  • #170 In Rails 4, if we return false from any of the before_ filters, the entire callback chain used to stop.
  • #172 No longer stops in Rails 5.
  • #173 Explicitly throw(:abort) to stop it.
  • #174 For older apps getting upgraded to Rails 5, the callback will still halt with returning false. as this is a breaking change.
  • #175 Once you are ready, toggle this flag and it will use new behaviour of throw.
  • #176 Some PRs which specifically improved performance in Rails 5.
  • #183 There is lot more than this in Rails 5.
  • #184 https://speakerdeck.com/sgrif/designing-a-great-ruby-api-how-were-simplifying-rails-5
  • #185 https://github.com/rails/sprockets/blob/3.x/UPGRADING.md
  • #186 https://github.com/turbolinks/turbolinks
  • #187 Where to go from here?
  • #188 If you are new to Rails, check out the Rails Doctrine to understand philosophy behind Rails.
  • #189 If you have an existing app, try upgrading Rails 5.0.0RC1 when it is out.
  • #190 Checkout Rails blog for new release announcements
  • #191 Rails twitter handle
  • #192 Daily news of what happens in Rails world. Subscribe to issues to get more details.
  • #193 Rails newsletter.
  • #194 Weekly scoop of things happened in Rails world.
  • #195 Our own blog series about new features in Rails 5.