Question
Rails before_action vs before_filter: What's the Difference in Rails 4?
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_filterafter_filteraround_filter
Later, Rails introduced clearer names:
before_actionafter_actionaround_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.
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.
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 , [, , , ]
= .find(params[])
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
-
Rails receives the request for
show. -
Rails checks whether any callbacks should run before
show. -
before_action :set_post, only: [:show]matches, so Rails runsset_post. -
Inside
set_post, Rails runs:
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]
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
.update(project_params)
redirect_to
render
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
Comparisons
| Concept | Meaning | Typical Use | Modern Preference |
|---|---|---|---|
before_filter | Run code before a controller action | Older Rails codebases | No |
before_action | Run code before a controller action | Modern Rails codebases | Yes |
after_action | Run code after a controller action | Logging, cleanup, headers | Yes |
around_action | Wrap code around a controller action | Timing, transactions, instrumentation | Yes |
before_filter vs before_action
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_actionruns before a controller action.- In Rails 4,
before_actionandbefore_filterare effectively aliases. - Use
before_actionin 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:orexcept:to avoid running callbacks where they do not belong.
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.
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." ]
Keep learning
Related questions
Calling a Class Method from an Instance in Ruby
Learn how to call a class method from an instance in Ruby using self.class, with examples, pitfalls, and practical usage patterns.
Calling an Overridden Monkey-Patched Method in Ruby
Learn how to call the original method when monkey patching in Ruby, including alias_method patterns, examples, pitfalls, and practical usage.
Convert a Unix Timestamp to Ruby DateTime
Learn how to convert Unix timestamps to Ruby DateTime and Time objects, with examples, differences, pitfalls, and practical Ruby usage.