Rails 5 is here: API mode, ActionCable, and a unified command
Rails 5 has reached its release candidate. A tour of what's new — first-class API-only apps, ActionCable, ApplicationRecord, the attributes API, required belongs_to, and the rails command swallowing rake.
Rails 5 has reached its release candidate, with the final release imminent. It is the biggest version bump in a while, and unlike the steady point releases of the 4.x line, it brings a couple of genuinely strategic additions — a first-class API mode and ActionCable — alongside a batch of smaller changes that touch everyday code. We have been running the betas; here is the tour of what actually matters.
API mode: Rails for JSON backends
The headline strategic change is --api mode. The rise of single-page apps and mobile
clients means a lot of new Rails apps are pure JSON backends with no server-rendered
views at all — and dragging the full middleware stack (cookies, sessions, flash, view
rendering) along for that ride was wasteful. Rails 5 makes API-only a first-class
choice:
rails new my_api --api
This generates a leaner app: a trimmed middleware stack, ActionController::API instead
of ActionController::Base (no view layer, no cookies by default), and generators that
do not scaffold views. You get the parts of Rails you actually want for an API — routing,
controllers, ActiveRecord, the ecosystem — without the weight of the parts you do not.
This is Rails acknowledging, officially, that “the backend behind a JS/mobile front end”
is a primary use case now, not an afterthought. For teams building SPAs against a Rails
API, it is the right default.
ActionCable: real-time in the box
The other strategic addition is ActionCable, which brings WebSockets into Rails with the same models, authentication, and conventions as everything else. It is significant enough that it deserves (and got) its own treatment, so I will not repeat the details here — but it belongs on any list of why Rails 5 matters. Together with API mode, it signals Rails’ answer to the JavaScript-heavy, real-time web: you can build the API and the live channel in the same framework you already know.
ApplicationRecord: a place for shared model code
A small but lovely change. Just as controllers have always inherited from your own
ApplicationController, models now inherit from ApplicationRecord:
# app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
class Post < ApplicationRecord
end
For years, “I want this behaviour on all my models” meant monkey-patching
ActiveRecord::Base itself — reopening a framework class, affecting every model in
every gem too. ApplicationRecord gives you a clean, app-owned base class to put shared
concerns, scopes, and helpers, without touching the framework. It is the obvious thing
that should always have existed, and now does.
The attributes API
A quietly powerful addition: you can now declare typed attributes on a model, including ones not backed by a database column, and control how values are cast:
class Product < ApplicationRecord
attribute :price_in_cents, :integer
attribute :discount, :decimal, default: 0
attribute :published_at, :datetime
end
This formalises type casting, gives virtual attributes a real home, and even lets you
define custom types. It is the foundation for cleaner form objects and value handling,
and it removes a lot of the ad-hoc attr_accessor-plus-manual-casting code apps used to
carry.
belongs_to is required by default
A change that will surprise you on upgrade if you are not ready for it: belongs_to
associations are now required by default. Previously a record could be saved with a
nil foreign key for a belongs_to; now that fails validation unless you say otherwise:
class Comment < ApplicationRecord
belongs_to :post # now required — a comment MUST have a post
belongs_to :author, optional: true # opt out explicitly when nil is valid
end
This is a good default — most belongs_tos genuinely should not be nil, and the old
behaviour let orphaned records slip through. But it will break existing apps that
relied on optional associations, so it is the first thing to check on upgrade. Add
optional: true where nil is legitimately allowed.
rails swallows rake
A workflow change you will notice immediately: the rails command now subsumes rake.
You can run rails db:migrate, rails test, rails routes — the tasks that used to
require rake now work under rails too:
rails db:migrate # was: rake db:migrate
rails db:seed
rails routes # was: rake routes
rake still works, but unifying everything under one command removes the perennial
“is it rake or rails?” hesitation. Small, but you will appreciate it every day.
The smaller additions
A few more worth knowing: Turbolinks 5 is a substantial rewrite that also powers a
native-app adapter; ActionController::Renderer lets you render templates outside a
controller (handy for rendering into background jobs or ActionCable broadcasts);
per-form CSRF tokens tighten security; and there is the usual deprecation cleanup.
The minimum Ruby is now 2.2.2, so make sure your runtime is current before upgrading.
Verdict
Rails 5 is a meaningful release, not a routine one. API mode and ActionCable are
strategic — they are Rails positioning itself for the JavaScript-frontend, real-time,
mobile-backend world that has become the norm, and they make Rails a credible choice for
those architectures rather than a server-rendered relic. The everyday changes —
ApplicationRecord, the attributes API, the unified rails command — are the kind of
quality-of-life improvements that make the framework nicer to live in. The one thing to
plan for on upgrade is required belongs_to; audit your optional associations first.
Beyond that it is a confident, forward-looking release, and an easy one to recommend
moving to.