Question

Rails before_action vs before_filter: What's the Difference in Rails 4?

rubyruby-on-railsruby-on-rails-4crud

Question

In Rails 4 and later, generated CRUD controllers use before_action instead of before_filter. Both appear to behave the same way. What is the difference between before_action and before_filter, and why does Rails use before_action in newer code?

Example controller generated by Rails:

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

  def show
  end

  def edit
  end

  def update
    if @post.update(post_params)
      redirect_to @post
    else
      render :edit
    end
  end

  def destroy
    @post.destroy
    redirect_to posts_url
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end
end

Short Answer

By the end of this page, you will understand how controller callbacks work in Rails, why before_action and before_filter look identical in Rails 4, and which one you should use in modern Rails applications. You will also see practical examples, common patterns, and mistakes to avoid when using callbacks in controllers.

Concept

In Rails controllers, a callback lets you run code automatically before, after, or around controller actions such as index, show, create, or update.

For example, you might want to:

  • load a record before show
  • check authentication before edit
  • verify authorization before destroy
  • set common data for multiple actions

Historically, Rails used names like:

  • before_filter
  • after_filter
  • around_filter

Later, Rails introduced clearer names:

  • before_action
  • after_action
  • around_action

In Rails 4, before_action was added as a clearer, preferred name for before_filter. For a time, they both worked and were effectively aliases of each other. In other words, they referred to the same callback mechanism.

Why the rename matters:

  • "Action" is clearer than "filter" for controller code.
  • It matches what is actually happening: code runs around a controller action.
  • It improves readability for beginners and teams.
  • New Rails code, guides, and generators follow the newer naming.

So the key idea is:

  • Behavior: effectively the same in Rails 4
  • Difference: mainly naming and convention
  • Recommendation: use before_action in modern Rails code

This matters in real programming because controller callbacks are used constantly for cross-cutting logic such as authentication, authorization, setup, and validation. Understanding them helps you read and maintain Rails applications more confidently.

Mental Model

Think of a controller action like entering a room to perform a task.

  • The action is the task you came to do.
  • A before_action is the checklist you complete before entering.
  • An after_action is the cleanup you do afterward.
  • An around_action is someone watching the whole process from start to finish.

before_filter and before_action are like two labels for the same checklist in Rails 4. Rails eventually preferred the label that makes more sense: action.

Take Quiz

Syntax and Examples

The basic syntax for a controller callback in Rails looks like this:

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

  def show
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end
end

What this does

Before Rails runs the show, edit, update, or destroy action, it first calls set_post.

That means @post is already available inside those actions and their views.

Older equivalent syntax

class PostsController < ApplicationController
  before_filter :set_post, only: [:show, :edit, :update, :destroy]

  def show
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end
end

In Rails 4, this is effectively the same idea.

Another common example: authentication

class AdminController < ApplicationController
  before_action :require_admin

  def dashboard
  end

  private

  def require_admin
    redirect_to root_path unless current_user&.admin?
  end
end

Here, require_admin runs before dashboard. If the user is not an admin, Rails redirects them instead of continuing normally.

Restricting callbacks

You can control where a callback runs:

before_action :authenticate_user!, only: [:edit, :update]
before_action :set_post, except: [:index, :new, :create]
  • only: means run the callback only for the listed actions.
  • except: means run it for every action except the listed ones.

Step by Step Execution

Consider this controller:

class PostsController < ApplicationController
  before_action :set_post, only: [:show]

  def show
    @title = @post.title.upcase
  end

  private

  def set_post
    @post = Post.find(params[:id])
  end
end

Now imagine a request comes in for:

GET /posts/5

Step-by-step

  1. Rails receives the request for show.

  2. Rails checks whether any callbacks should run before show.

  3. before_action :set_post, only: [:show] matches, so Rails runs set_post.

  4. Inside set_post, Rails runs:

    @post = Post.find(params[:id])
    
  5. params[:id] is 5, so Rails looks up the post with ID 5.

  6. @post is now available to the controller.

  7. Rails enters the show action.

  8. The action runs:

    @title = @post.title.upcase
    
  9. Rails renders the show view.

  10. The view can use @post and @title.

Important takeaway

The callback runs before the action body, which is why setup logic like loading a model is a common use case.

Real World Use Cases

Controller callbacks are very common in real Rails apps.

1. Authentication

before_action :authenticate_user!

Used to make sure a user is signed in before accessing protected pages.

2. Loading shared records

before_action :set_order, only: [:show, :update, :cancel]

Avoids repeating @order = Order.find(params[:id]) in multiple actions.

3. Authorization

before_action :require_admin, only: [:destroy]

Prevents non-admin users from accessing sensitive actions.

4. Setting common view data

before_action :load_categories

Useful when many actions need the same sidebar or navigation data.

5. Request preparation

before_action :normalize_search_params, only: [:index]

Can clean or transform input before an action uses it.

6. Auditing or logging with related callbacks

Although before_action is common, teams may also use after_action or around_action for logging, timing, or tracking request behavior.

Take Quiz

Real Codebase Usage

In real projects, developers usually use callbacks for shared controller concerns, but they try to keep callbacks focused and easy to understand.

Common patterns

Guard clauses for access control

before_action :require_login

private

def require_login
  return if current_user
  redirect_to login_path, alert: "Please sign in"
end

This is simple and readable: allow the request if the condition is met; otherwise redirect early.

Shared setup methods

before_action :set_project, only: [:show, :edit, :update]

private

def set_project
  @project = Project.find(params[:id])
end

This avoids duplication across multiple actions.

Using callbacks with strong parameters indirectly

Callbacks often prepare state, while the action handles saving:

def update
  if @project.update(project_params)
    redirect_to @project
  else
    render :edit
  end
end

Keeping callbacks narrow

Good callbacks usually do one thing:

  • authenticate
  • load a resource
  • verify permissions
  • prepare shared data

When teams become cautious

Too many callbacks can make controller flow harder to follow because behavior is happening "behind the scenes." In larger codebases, developers often:

  • keep callback names explicit
  • avoid complex business logic in callbacks
  • move heavy logic into service objects or models when appropriate
  • use only: and except: carefully so callback scope stays obvious

Common Mistakes

1. Thinking before_filter and before_action are different features in Rails 4

In Rails 4, they are effectively aliases for the same controller callback behavior.

2. Using old naming in new code

Broken from a style perspective, even if it may still work in some versions:

before_filter :set_post

Preferred modern style:

before_action :set_post

Use the current convention so your code matches Rails guides and generators.

3. Forgetting to limit the callback to relevant actions

Problematic:

before_action :set_post

If index or new does not have params[:id], this may fail.

Better:

before_action :set_post, only: [:show, :edit, :update, :destroy]

4. Putting too much logic inside a callback

Hard to read:

def set_post
  @post = Post.find(params[:id])
  @comments = @post.comments.recent.limit(20)
  @author = @post.author
  @permissions = PermissionService.new(current_user, @post)
  @analytics = AnalyticsService.track(@post)
end

Better: keep callbacks focused and move extra logic where it belongs.

5. Hiding important behavior

If many callbacks run before an action, it becomes hard to understand what the action really depends on.

To avoid this:

  • use clear names like set_post or require_admin
  • avoid unnecessary callbacks
  • keep callback chains short

6. Assuming a callback always halts execution automatically

A callback can redirect or render, but you should understand the flow clearly in your Rails version and code style.

Example:

def require_admin
  redirect_to root_path unless current_user&.admin?
end

Be intentional about what should happen when access is denied.

Comparisons

ConceptMeaningTypical UseModern Preference
before_filterRun code before a controller actionOlder Rails codebasesNo
before_actionRun code before a controller actionModern Rails codebasesYes
after_actionRun code after a controller actionLogging, cleanup, headersYes
around_actionWrap code around a controller actionTiming, transactions, instrumentationYes

before_filter vs before_action

  • In Rails 4, they behave the same for practical purposes.
  • before_action is the newer, clearer name.
  • Rails generators and guides prefer before_action.

Callback vs writing code directly inside each action

ApproachProsCons
CallbackReduces duplication, centralizes shared setupCan hide control flow
Inline code in each actionExplicit and easy to traceRepetition across actions

only: vs except:

OptionMeaningBest when
only:Run for listed actions onlyA callback applies to a small set of actions
except:Run for all actions except listed onesA callback applies almost everywhere

As a rule of thumb, only: is often easier for beginners to read because it shows exactly where the callback applies.

Take Quiz

Cheat Sheet

# Modern Rails callback
before_action :method_name

# Older alias seen in older code
before_filter :method_name

# Limit callback to certain actions
before_action :set_post, only: [:show, :edit, :update, :destroy]

# Exclude certain actions
before_action :authenticate_user!, except: [:index, :show]

Key facts

  • before_action runs before a controller action.
  • In Rails 4, before_action and before_filter are effectively aliases.
  • Use before_action in modern code.
  • Common uses:
    • authentication
    • authorization
    • loading records
    • setting shared data
  • Keep callbacks small and focused.
  • Prefer clear method names like set_post, require_login, load_categories.
  • Use only: or except: to avoid running callbacks where they do not belong.

Good pattern

before_action :set_post, only: [:show, :edit, :update, :destroy]

Avoid

before_action :do_everything

FAQ

Is before_filter deprecated in Rails 4?

Rails 4 introduced before_action as the preferred name. In later Rails versions, before_filter was deprecated and then removed, so modern code should use before_action.

Do before_action and before_filter behave differently?

In Rails 4, for normal controller usage, they are effectively the same callback mechanism.

Why did Rails rename before_filter to before_action?

Because before_action is clearer and better describes that the callback runs before a controller action.

Should I replace before_filter in older projects?

If you are maintaining an older app, updating to before_action can improve consistency and help with future Rails upgrades.

When should I use before_action?

Use it for shared controller setup such as loading records, checking authentication, or enforcing authorization.

Can I overuse controller callbacks?

Yes. Too many callbacks can make controller flow hard to follow. Keep them small, clear, and limited to shared concerns.

What is the difference between before_action and around_action?

before_action runs before the action. around_action wraps the whole action, so it can run code both before and after it.

Take Quiz

Mini Project

Description

Build a small Rails-style controller example that uses before_action to load a record and protect an admin-only action. This project demonstrates the most common real uses of controller callbacks: shared setup and access control.

Goal

Create a controller that loads an article before selected actions and blocks non-admin users from deleting articles.

Requirements

[ "Create an ArticlesController with show, edit, update, and destroy actions.", "Use before_action to load the article for actions that need params[:id].", "Use before_action to restrict destroy to admin users only.", "Keep callback methods in the private section.", "Redirect non-admin users instead of allowing destroy to continue." ]

Take Quiz

Keep learning

Related questions

View more