Before and after filters let you run code automatically before or after certain actions in your Rails controller. This helps keep your code clean and organized.
You want to check if a user is logged in before showing a page.
You need to load some data before running an action.
You want to log information after an action finishes.
You want to clean up or reset something after an action runs.
This runs log_action after all actions except index.
Ruby on Rails
after_action :log_action, except: [:index]
def log_action
Rails.logger.info "Action completed"
end
Sample Program
This controller loads the article before show and edit actions. After show, it logs that the article was viewed.
Ruby on Rails
class ArticlesController < ApplicationController
before_action :set_article, only: [:show, :edit]
after_action :log_view, only: [:show]
def show
# show article
end
def edit
# edit article
end
private
def set_article
@article = Article.find(params[:id])
end
def log_view
Rails.logger.info "Article #{@article.id} was viewed"
end
end
OutputSuccess
Important Notes
Filters help avoid repeating code in each action.
You can use only and except to control which actions run the filters.
Filters run in the order they are defined.
Summary
Before filters run code before controller actions.
After filters run code after controller actions.
Use filters to keep your controller code clean and DRY.
Practice
(1/5)
1. What is the main purpose of a before_action filter in a Rails controller?
easy
A. To run code before a controller action executes
B. To run code after a controller action executes
C. To skip a controller action entirely
D. To define a new controller action
Solution
Step 1: Understand the role of filters
Filters in Rails run code around controller actions to modify behavior.
Step 2: Identify the timing of before_action
before_action runs code before the main action method executes.
Final Answer:
To run code before a controller action executes -> Option A
Quick Check:
before_action = runs before action [OK]
Hint: Before filters run code before actions start [OK]
Common Mistakes:
Confusing before_action with after_action
Thinking before_action skips actions
Assuming before_action defines new actions
2. Which of the following is the correct syntax to define an after filter named log_action in a Rails controller?
easy
A. after_filter :log_action
B. after :log_action
C. before_action :log_action
D. after_action :log_action
Solution
Step 1: Recall the modern syntax for after filters
Rails uses after_action to define code that runs after controller actions.
Step 2: Check each option
after_filter :log_action uses deprecated after_filter. after_action :log_action uses correct after_action. before_action :log_action is for before filters. after :log_action is invalid syntax.
Final Answer:
after_action :log_action -> Option D
Quick Check:
Use after_action for after filters [OK]
Hint: Use after_action, not after_filter, for after filters [OK]
Common Mistakes:
Using deprecated after_filter instead of after_action
Mixing before_action with after filters
Incorrect syntax like 'after :method'
3. Given this controller code:
class PostsController < ApplicationController
before_action :set_post
after_action :log_post
def show
render plain: @post.title
end
private
def set_post
@post = Post.find(params[:id])
end
def log_post
Rails.logger.info "Post viewed: #{@post.id}"
end
end
What will be the output when GET /posts/5 is called, assuming the post with ID 5 has title "Hello"?
medium
A. The page shows "Hello" and logs "Post viewed: 5" after rendering
B. The page shows "Hello" but does not log anything
C. The page shows nothing and logs "Post viewed: 5"
D. An error occurs because @post is not set
Solution
Step 1: Understand filter order and effects
before_action :set_post runs before show, setting @post. after_action :log_post runs after show completes.
Step 2: Trace the request flow
When show runs, @post is set, so render plain: @post.title outputs "Hello". After rendering, log_post logs "Post viewed: 5".
Final Answer:
The page shows "Hello" and logs "Post viewed: 5" after rendering -> Option A
Quick Check:
before_action sets data, after_action logs after render [OK]
Hint: before_action sets data, after_action runs after response [OK]
Common Mistakes:
Thinking after_action runs before rendering
Assuming @post is nil in show
Confusing logging output with page content
4. Identify the error in this controller code:
class UsersController < ApplicationController
before_action :authenticate_user
after_action :clear_session
def index
# list users
end
private
def authenticate_user
redirect_to login_path unless current_user
end
def clear_session
session[:temp] = nil
end
end
medium
A. The methods authenticate_user and clear_session must be public
B. The before_action should be after_action for authentication
C. The after_action runs even if redirect happens, causing errors
D. There is no error; the code works as expected
Solution
Step 1: Analyze filter behavior with redirects
If authenticate_user redirects, the action does not run, but after_action still runs.
Step 2: Understand consequences of after_action after redirect
Running clear_session after redirect can cause unexpected side effects or errors.
Final Answer:
The after_action runs even if redirect happens, causing errors -> Option C
Quick Check:
after_action runs even after redirect [OK]
Hint: after_action runs even if before_action redirects [OK]
Common Mistakes:
Assuming after_action skips on redirect
Thinking authentication should be after_action
Believing private methods must be public
5. You want to run a before_action filter named check_admin only before the edit and update actions in a Rails controller. Which is the correct way to write this?
hard
A. before_action :check_admin, except: [:edit, :update]
B. before_action :check_admin, only: [:edit, :update]
C. after_action :check_admin, only: [:edit, :update]
D. before_filter :check_admin, only: [:edit, :update]
Solution
Step 1: Identify correct filter type and options
Use before_action to run code before actions. Use only: to limit to specific actions.