Using Before and After Filters in Rails Controllers
📖 Scenario: You are building a simple Rails web app to manage a list of books. You want to run some code automatically before and after certain actions in your controller to prepare data and log activity.
🎯 Goal: Create a Rails controller called BooksController that uses before_action and after_action filters. The before_action will set a variable with a welcome message before the index action. The after_action will log a message after the index action runs.
📋 What You'll Learn
Create a BooksController class inheriting from ApplicationController
Add a before_action filter named set_welcome_message that runs only before the index action
Add an after_action filter named log_index_access that runs only after the index action
Define the index action that sets an instance variable @books to an array of book titles
Define the set_welcome_message method that sets @welcome_message to the string "Welcome to the Books List!"
Define the log_index_access method that calls Rails.logger.info with the message "Index action was accessed"
💡 Why This Matters
🌍 Real World
Before and after filters are used in Rails apps to run code automatically around controller actions. For example, setting up data, checking permissions, or logging activity without repeating code in every action.
💼 Career
Understanding filters is important for Rails developers to write clean, maintainable controllers and implement common behaviors like authentication, logging, and data preparation efficiently.
Progress0 / 4 steps
1
Create the BooksController with the index action
Create a class called BooksController that inherits from ApplicationController. Inside it, define a method called index that sets an instance variable @books to the array ["The Hobbit", "1984", "Brave New World"].
Ruby on Rails
Hint
Remember to use def to define the index method and set @books inside it.
2
Add a before_action filter to set a welcome message
Add a before_action filter called set_welcome_message that runs only before the index action. Then define the set_welcome_message method that sets @welcome_message to the string "Welcome to the Books List!".
Ruby on Rails
Hint
Use before_action :set_welcome_message, only: [:index] and define the method below the index action.
3
Add an after_action filter to log access
Add an after_action filter called log_index_access that runs only after the index action. Then define the log_index_access method that calls Rails.logger.info with the message "Index action was accessed".
Ruby on Rails
Hint
Use after_action :log_index_access, only: [:index] and define the method that logs the message.
4
Complete the controller with all filters and actions
Ensure the BooksController class includes the before_action filter set_welcome_message for index, the after_action filter log_index_access for index, and defines the methods index, set_welcome_message, and log_index_access exactly as specified.
Ruby on Rails
Hint
Review all previous steps and ensure the controller has all filters and methods exactly as specified.
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.