Why I don't use the 'except' and 'only' params to Rails before_action
A before_action
that runs before every action is a useful pattern which helps us avoid forgetting to call some important piece of code before every action in the controller e.g. authentication or authorization.
However I think that, on balance, before_action
with only:
or except:
params does more harm than good to a codebase.
Reasonable people disagree on this e.g. Rails scaffold uses before_action
with only
/except
for setting instance vars.
I’ll make my case below so you can make up your own mind about it.
Pro: Less typing, shorter methods
You save a few characters of typing and your methods are a few lines shorter which might make rubocop happier.
Con: It scales badly
It doesn’t set a good example. Codebases tend to get more of what they have. The next dev who comes along will tend to do more of what is already there.
before_action
with only
/except
gets grim when you get a bunch of them together e.g.
# Day 1, workin' on that organisations feature oh yeah!
# No problem here, pretty easy to read and understand.
class OrganisationsController < AdminController
before_action :set_organisation, only: %i[show edit update destroy]
def index
# ...
# Day 100, adding even more stuff to organisations...
# What about now?
# How hard did you have to run your mental ruby interpreter to figure out which
# of these actions run before the controller action you care about?
class OrganisationsController < AdminController
before_action :set_organisation, only: %i[show edit update destroy]
before_action :set_other, :only: %i[edit index destroy]
before_action :set_other_1, :only: %i[edit index show]
before_action :set_other_2, except: %i[show destroy]
before_action :do_some_other_thing, only: %i[show]
def index
# ...
I think in almost all cases it is better to just type code directly into the controller action. If there is enough code to warrant pulling into a private method then that’s fine - just call the private method in the controller action.