Rails 5: A lot more than ActionCable!

Rails 5: A lot more than ActionCable!

Posted by Parth Modi

12 Aug 20 5 min read

Rails 5 and 5.1 brings some awesome features such as Attributes API, API mode, ActionCable, Turbolinks, and much more!

Setting up rails 5 along-with current version of rails such as Rails 4 is explained in the first part of Rails 5 series 4 features to watch for in Rails 5.1 beta.

Attributes API:

If you are working with rails, you definitely used attr_accessor at some point. It’s pretty useful functionality which defines getter and setter for an attribute which might not exist in the database. For simple use-cases, this was enough, but it lacked some features, such as assigning the type of attributes, setting default values, validations, etc.

I preferred not to use attr_accessor inside my models but used them sparingly across PORO and Service objects, but this new API will change the way I work with virtual attributes in models.

Newly added attributes API allows many features such as:

  • Model Attributes doesn’t need to be backed by a database.
  • You can override type defined by the active record, to some another type or custom types.
  • Default values can be assigned for attributes.
  • If the attribute is backed by a database field, then you can query it by converting it to SQL type with serialization.

This API provides a cleaner approach to assigning predefined types or custom types and default values to virtual attributes. To understand how it works, let’s look at how active records handle typecasting to and from the database.

After submitting forms, AR (Active Record) casts the data received from the form to the appropriate database type before saving. When data is fetched from the database, it’s again typed cast, and serialized accordingly. One important thing to notice here is that AR automatically handles type casting without needing you to specify whether it is an integer, string, or some other type.

The Attributes API overrides this automatic type detection with user-specified type.

For example, let’s create a User model with the following database fields:

create_table :users do |t|
t.string :first_name
t.string :last_name
t.integer :age
t.timestamps
end

And in the model, define the name as a virtual attribute with the new Attribute API, and full_name with the older approach.

class User < ApplicationRecord
  # rails 4 way of defining virtual attribute
  attr_accessor :full_name
  
  # new rails 5 way of defining virtual attributes with datatype and default values
  attribute :name, :string, default: -> {  "No Name" }
  attribute :age, :float, default: 99

  before_save :assign_name
  before_save :assign_full_name
   
  def assign_name
    self.name = "#{first_name} #{last_name}"
  end
  def assign_full_name
    self.full_name = "#{first_name} #{last_name}"
  end
end

In rails console: 
irb:> User.new
=> #<User id: nil, first_name: nil, last_name: nil, age: "99", created_at: nil, updated_at: nil, name: "No Name">
irb:> u = User.new(first_name: "Harry", last_name: "Potter")
irb:> u.save
irb:> u
=> #<User id: 1, first_name: "Harry", last_name: "Potter", age: 99.0, created_at: "2017-03-29 16:30:16", updated_at: "2017-03-29 16:30:16", name: "Harry Potter">

One important change is the ability to give default values. name and age, both fields can be initialized with default values and if no values are given, these default values can be used.

Another useful change is the ability to override the default database field type. age is an integer-type value, and can be cast to float.

Attributes API documentation would be a good place to refer and understand how Attributes API can be used.

The go-rails screencast discusses very nicely how attributes API can be utilized in different scenarios.

[@portabletext/react] Unknown block type "separator", specify a component for it in the `components.types` prop

API mode:

I have been using Rails 4 for API—only applications and this feature will be definitely useful. By default, rails consist of an assets pipeline, lots of middleware, and unnecessary overhead that is not required for API-only applications.

Removing all that unnecessary overhead makes rail applications very lightweight and faster. Adding rails — API gem helped get rid of some middleware, asset pipeline, some specific controller modules, etc. This gem provides support for both creating new rails API-only applications and migrating existing rails applications to API-only applications. It lets you choose specific middleware to use, and which controller modules to use.

Rails 5 merges the rails-API gem into rails, and provides the option to create API-only application with the following command:

rails new my-app --api

You can check rails-api or find various guides for using rails in API mode.

[@portabletext/react] Unknown block type "separator", specify a component for it in the `components.types` prop

Of course, ‘The ActionCable’:

ActionCable is the most widely discussed feature of Rails 5. After seeing lots of tutorials with a title similar to ‘Let’s create a chat application with Ruby on Rails ActionCable’, I lost the desire to create some random chat app that does nothing significant.

But then I came across this awesome talk ‘Not just another chat app' by “Jesse Wolgamott” where he nicely explains the history of action cable and what can be done with action cable apart from just real-time chat application.

In short, ActionCable can be used for:

  • Live Chat
  • Streaming of data
  • Collaboration Tools — such as when multiple users are working on the same document
  • Anywhere when you want to push real-time data and content to users

However, If content doesn’t need to be updated almost instantly then Action Cable can be overkill. Maintaining live connections in ActionCable consumes resources and many of times simple polling can be a lot more beneficial.

What’s new in Routes?

Listing Routes:

The most frequently used command for me was `rake routes`, and finding a specific route from a long list of routes was easy with:

rake routes | grep users

This can be replaced with:

# this shows all routes for users_controller
rake routes -c users# however, for grep-like pattern matching, you can use
rake routes -g users

TL;DR:

Rails 5 brings WebSockets to support with ActionCable, Turbolinks 5, API mode for backend-specific rails applications, and awesome Attributes API.

This is second part of two part series on new significant features in rails 5.1 beta and 5. To dive deep into rails 5 specific features, checkout first part of article series 4 features to watch for in Rails 5.1 beta!

Feel free to talk about the features you are excited about in Rails 5 share ❤ the article and check out other articles below:

[@portabletext/react] Unknown block type "urllink", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "urllink", specify a component for it in the `components.types` prop
[@portabletext/react] Unknown block type "separator", specify a component for it in the `components.types` prop

About Solute TechnoLabs LLP

We are a bunch of passionate technocrats who love building products and applications that we take pride in. Our mobile and web applications have been downloaded and used by millions and we’re here to change the internet: One piece at a time!