What is new in Rails 5 (Features + Changes)
This article will discuss what is new in Rails 5. The changes like rails instead of rake, ruby 2.2.1+ support, performance improvements, action cable, rails api application will be discussed.
1. use rails instead of rake
There are many commands in the Rails framework that are addressed by rake. it is kind of unclear on which command needs execution by rails
and which commands need to be executed using rake
. Thus, it’s difficult for new users who get on with Rails to use these commands. So, to make the behaviour uniform all the commands starting with rake
will also be executed if tried with rails
command.
E.g. Previously for data migration in Rails - we needed to enter command
rake db:migrate
now, rake db:migrate can be achieved using
rails db:migrate
command as well.
Here is the issue that is aimed to achieve this with Rails 5 release - https://github.com/rails/rails/issues/18878
Although, development on this is in progress in following pull requests - this would eventually make up into Rails 5
https://github.com/rails/rails/pull/21012
https://github.com/rails/rails/pull/21254
Here is an excellent article that explains how Rails 5 brings consistency by wrapping all rake commands using rails.
2. rake restart
Now to restart the rails server there is a command that can help you restart the rails server.
What does it do? - It just touches the tmp/restart.txt
file.
Command:
rake restart
Here is the pull request that merged this change: https://github.com/rails/rails/pull/18965/
3. Ruby 2.2.1+ support only
Rails marked to use Ruby 2.2.2+ version. Symbols were not getting garbage collected prior to Ruby 2.2.1. From the release of Ruby 2.2.1, symbols are garbage collected as well.
Advantages of Symbol GC available in Ruby
Ruby Garbage Collection Example:
The above example shows that symbols are not garbage collected in ruby 2.1.2
And this output clearly shows how symbols get garbage collected in Ruby 2.2.1+
When we invoke GC it may/may not start garbage collection - but it will clean symbols that have no reference as shown above.
- When symbols were allocated - total size of symbols = 12872
- After we invoked Garbage Collector - total size of symbols = 3316
Thus, Garbage collection is very handy feature of Ruby 2.2.1+ which will be explored by Rails 5+ applications.
Here is the Merged pull request link where Rails marked to use Ruby 2.2.2+ version
https://github.com/rails/rails/pull/19752
4. Performance improvements by Richard Schneeman schneeman
There is lot to talk about this. Richard Schneeman is a Ruby developer at Heroku and loves contributing to Rails. Recently he had merged a lot of performance improvement to Rails. The patch has improved the performance almost 11%.
In his own blog post -Richard Schneeman has posted following image - which rightly defines his commit
Here, we’ll be discussing few of the major improvements from this patch -
String#freeze optimizations
If you’re not familiar with benchmark/ips, please explore benchmark-ips gem.
Explanation
Using freeze on strings returns same string object upon invoking multiple times. Thus, in above example freeze approach is giving more number of iterations per second.
Conclusion
Basically this is done to de-duplicate the strings at compile time in VM.
'string'.freeze
is optimized at compile time
and
returns single shared frozen string instead of allocating a new string and returning back.
Reference: Frozen String Literals
Merged Rails Commit: String#freeze optimizations
Avoid Calling to_s on nil
When we call to_s on nil object then - it allocates empty string object and returns. Thus, this is a new string object allocation. If you’re doing this in loop or calling it multiple times somehow then it will be creating a lot of string objects causing increase in memory allocation.
object.to_s if !object.nil?
Basically performing to_s operation only if object is not a nil object.
Merged Rails Commit- Avoid calling to_s on nil in journey/formatter
In this commit conditions are modified in such a way to avoid calling to_s on nil object.
Remove Array allocation if not needed
Array should not be allocated if not needed. Basically if you are initializing a variable by an empty array and there are conditions below which would add values to array or something then just delay initialization of variable to a array as possible as you can.
E.g.
var = []
some_object = 54
if some_object == 54
var << 'found'
end
From above code, we need to add found
string to array var
only if some_object
has value 54
Right way -
var = nil
some_object = 54
if some_object == 54
var ||= []
var << 'found'
end
Basically we have delayed initialization i.e. allocation until needed.
Merged Rails Commits
1) Remove (another) array allocation
Merged pull request - Beyond Ludicrous Speed
5. Rails 5: ActionCable
ActionCable is Framework for Real-Time communication over WebSockets. ActionCable is integrated websocket for Rails Applications. ActionCable is being implemented as a gem at Rails/ActionCable. This would be Merged with Rails once implementation is completed and stable.
What problem is solved by ActionCable?
Suppose you have a mailing application, where you would want to update a new email in the browser as soon as received.
Possible Solution
You can keep polling after some time interval to server side (backend) and if you get new email in response then update the DOM with the content received from backend via javascript. But, this would result in many number of polls void/useless.
WebSocket is a protocol providing full-duplex communication channels over a single TCP connection. [Source]
ActionCable Terminologies:
Cable - Cable is just like a way to communicate between browser (client) and server through a connection which is made using websockets
Connection - Connection is created using WebSockets
Channel - A Cable can have multiple channels. Channels need to be created to send or receive for various functionalities that need solution to the similar problem discussed above.
Broadcast - Server can broadcast to different channels particular data
ActionCable Examples
If you are interested in exploring and implementing ActionCable for your Rails application - Try ActionCable examples provided.
If you’re interested in contributing to ActionCable - visit Rails/ActionCable
6. Rails 5: Rails API only application
Many a times - people implement Backend in Rails just as a API server - Rails API only application is designed for such use cases.
E.g. If you’re implementing a Mobile Application where you don’t need Web UI implementation - Then you can implement Backend part in Rails and expose APIs which would be called from Mobile Application (either Android / iOS or any other platform)
So, in such cases you don’t need entire Rails Stack for your Application. To solve this - Rails 5 has implemented API only option - which would create minimalistic Rails application.
Why API app instead of complete Rails App?
When you don’t need entire Rails middleware stack. Basically you don’t need ActionController::Base, Asset Pipeline, Views, Helpers etc. - then you should user Rails API app.
Command to create Rails API application:
rails new my_rails_api_app --api
Convert Existing Rails Application to API application
Open your config/application.rb file and add following line -
config.api_only = true
Edit your app/controllers/application_controller.rb
instead of,
class ApplicationController < ActionController::Base
end
do this: inherit from ActionController::API
class ApplicationController < ActionController::API
end
7. ActiveRecord Improvements
ActiveRecord::Base#where.or
In last version of Rails - ActiveRecord::Base#where.not was introduced. With Rails 5 - ActiveRecord::Base#where.or is introduced. You can perform SQL or operation with Rails way.
Example -
Post.where('id = 1').or(Post.where('id = 2'))
This will create a query like -
# => SELECT * FROM posts WHERE (id = 1) OR (id = 2)
Here is a Merged Commit and Corresponding Pull Request.
Lastly, we’re leaving you with a talk about the Rails 5 Features You Haven’t Heard About by Sean.DHH
Please feel free to suggest anything and comment down below.
Subscribe to Ruby in Rails
Get the latest posts delivered right to your inbox