29
.
04
.
2024
25
.
07
.
2022
Ruby on Rails
Backend
Tutorial

Should I use Action Filters?

Mateusz Woźniczka
Ruby Developer

You are developing your first Rails app, which is most likely a Blog - we all have been there :).

At some point, you end up with a controller created by scaffold, which looks more or less, like this:


class PostsController < ApplicationController
  before_action :set_post, only: %i[ show edit update destroy ]

  # GET /posts or /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1 or /posts/1.json
  def show
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # (...) update create and destroy actions are hidden
  # for the sake of readability

  private
    # Use callbacks to share common setup or constraints between actions.
  def set_post
    @post = Post.find(params[:id])
  end
end

Rails generated set_post method, and even tells you to Use callbacks to share common setup or constraints between actions.

The code is DRY as it can be, you have a nice looking before_action, so it must be the famous Rails way of doing things - and it is.

However some developers (including me) are writing code in a different way.

Why?

Let's assume, that we stick to Filters (it is the official name of this feature despite the fact, that scaffold is calling it callback) - after implementing additional functionalities we can end up with something like this:


class PostsController < ApplicationController
  before_action :set_post, only: %i[ show edit update destroy ]
  before_action :set_user, only: %i[ edit update ]
  before_action :check_admin, only: :destroy
  after_action :send_email, only: %i[ update destroy ]

  # GET /posts or /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1 or /posts/1.json
  def show
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
  end

  # (...)

end

Reading edit action has just become a bit harder, because you ended up with an empty action, which is in fact does quite a lot of things.

So in order to understand what is going on there you have to jump back and forth between the filters. And this is relatively simple action - you can image what happens, when the app grows.

What is the 'right' way?

Alternative approach is actually really simple - just call the method inside the action. That's it.

Then you end up with code like this:


class PostsController < ApplicationController

  # GET /posts or /posts.json
  def index
    @posts = Post.all
  end

  # GET /posts/1 or /posts/1.json
  def show
    set_post
  end

  # GET /posts/new
  def new
    @post = Post.new
  end

  # GET /posts/1/edit
  def edit
    set_post
  end

  # (...) update create and destroy actions are hidden
  # for the sake of readability

  private
    # Use callbacks to share common setup or constraints between actions.
  def set_post
    @post = Post.find(params[:id])
  end
end

Now, at first glance at edit or show action you know which method is called.

Got it - let's forget about Action Filters

Actually, not really - they are used for authentication / authorization - you will more than once see code like this, especially when working with devise gem:


class PostsController < ApplicationController
  before_action :authenticate_user!
end

Wrap up

If you are not dealing with authentication / autorization try avoiding using Action Filters (referred by some as ''callbacks'') - they make code harder to read.

Mateusz Woźniczka
Ruby Developer

Check my Twitter

Check my Linkedin

Did you like it? 

Sign up To VIsuality newsletter

READ ALSO

A journey of a thousand miles begins with workshops

11
.
06
.
2025
Michał Piórkowski
Software
HR

CS Lessons #002: Data structures

11
.
06
.
2025
Michał Młoźniak
Ruby
Software

Summary of Phoenix workshop at Visuality

11
.
06
.
2025
Karol Słuszniak
Ruby on Rails
Visuality
Backend

CS Lessons #001: Working with binary files

11
.
06
.
2025
Michał Młoźniak
Ruby
Software

CS Lessons #000: Introduction and motivation

11
.
06
.
2025
Michał Młoźniak
Ruby
Software

Working with 40-minute intervals

11
.
06
.
2025
Sakir Temel
Software
HR

THE MATURE TECH STARTUP DILEMMA: WHAT'S NEXT

11
.
06
.
2025
Susanna Romantsova
Startups

Win MVP workshop!

11
.
06
.
2025
Susanna Romantsova
Startups

FINTECH WEEK IN OSLO: WHATs & WHYs

11
.
06
.
2025
Susanna Romantsova
Conferences

MY FIRST MONTH AT VISUALITY

11
.
06
.
2025
Susanna Romantsova
Visuality
HR

NASA 1st global hackaton in Poland? Visuality Created it!

11
.
06
.
2025
Rafał Maliszewski
Ruby on Rails

Berlin StartupCamp 2016 summary

11
.
06
.
2025
Michał Piórkowski
Conferences
Startups

Investment Days for productivity

11
.
06
.
2025
Rafał Maliszewski
Visuality
HR

Happy new year

11
.
06
.
2025
Michał Piórkowski
Visuality

Does Norway need Polish software development?

11
.
06
.
2025
Rafał Maliszewski
Ruby on Rails

Visuality is 8 years old

11
.
06
.
2025
Michał Piórkowski
Visuality
Backend

Use less javascript plugins

11
.
06
.
2025
Michał Młoźniak
Frontend

Front-Trends 2015

11
.
06
.
2025
Adam Król
Frontend

Automatic door opener controlled through slack

11
.
06
.
2025
Sakir Temel
Backend
Software
Tutorial

Wolves Summit

11
.
06
.
2025
Michał Piórkowski
Conferences
Business

Berlin Startup Camp

11
.
06
.
2025
Michał Piórkowski
Ruby on Rails
Conferences

Why you shouldn't work at Visuality

11
.
06
.
2025
Michał Piórkowski
Visuality
HR

SaaS Meetup #People

11
.
06
.
2025
Michał Piórkowski
Conferences

Startup Safary Berlin 2015

11
.
06
.
2025
Michał Piórkowski
Conferences