We write about Ruby on Rails, React.js, React Native, remote work, open source, engineering and design.
Rails 6.0 was recently released.
When working
in a team
on a Rails application,
we often bump into PendingMigrationError
or other errors that need us
to run a rails command,
rake task etc.
Rails introduced a way to resolve such frequent errors in development from error page itself.
Rails 6 added
ActiveSupport::ActionableError
module to define actions
we want perform on errors,
right from the error page.
For example, this is how
PendingMigrationError
page looks like in Rails 6.
By default, a button is added
on error screen that says
Run pending migrations.
Clicking on this button
would dispatch
rails db:migrate
action.
Page will reload
once migrations run successfully.
We can also define custom actions to execute on errors.
We need to include
ActiveSupport::ActionableError
module in our
error class.
We can monkey patch an
existing error class or
define custom error class.
#action
api is provided
to define
actions on error.
First argument in #action
is name of the action.
This string would be displayed
on the button on error page.
Second argument is a block
where we can write
commands or code
to fix the error.
Let's take an example of seeding posts data from controller, if posts not already present.
1
2# app/controllers/posts_controller.rb
3
4class PostsController < ApplicationController
5
6def index
7@posts = Post.all
8if @posts.empty?
9raise PostsMissingError
10end
11end
12
13end
1
2# app/errors/posts_missing_error.rb
3
4class PostsMissingError < StandardError
5
6include ActiveSupport::ActionableError
7
8action "seed posts data" do
9Rails::Command.invoke 'posts:seed'
10end
11
12end
13
1
2# lib/tasks/posts.rake
3
4namespace :posts do
5
6desc 'posts seed task'
7task :seed do
8Post.create(title: 'First Post')
9end
10
11end
1
2# app/views/posts/index.html.erb
3
4<% @posts.each do |post| %>
5<%= post.title %>
6<% end %>
Let's check /posts
(posts#index
action)
when no posts are present.
We would get an error page
with an action button on it
as shown below.
Clicking on
seed posts data action button
will run our rake task and create posts.
Rails will automatically reload
/posts
after running rake task.
ActionDispatch::ActionableExceptions
middleware
takes care of invoking actions
from error page.
ActionableExceptions
middleware
dispatches action to
ActionableError
and redirects back
when action block has successfully run.
Action buttons
are added
on error page
from
this middleware template.
Checkout the pull request for more information on actionable error.