Bird
Raised Fist0
Ruby on Railsframework~15 mins

Before and after filters in Ruby on Rails - Deep Dive

Choose your learning style10 modes available
Overview - Before and after filters
What is it?
Before and after filters in Rails are special methods that run automatically before or after certain actions in a controller. They let you run shared code like checking if a user is logged in or cleaning up data without repeating yourself. These filters help organize your code and keep it clean by separating common tasks from the main action logic. They are part of Rails controllers, which handle web requests and responses.
Why it matters
Without before and after filters, you would have to write the same code inside every action that needs it, making your code messy and error-prone. Filters save time and reduce bugs by centralizing common tasks like authentication or logging. This makes your app easier to maintain and extend. Imagine having to check if a user is logged in inside every page's code manually — filters automate that for you.
Where it fits
Before learning filters, you should understand basic Rails controllers and actions. After mastering filters, you can explore more advanced Rails features like concerns, callbacks, and middleware. Filters are a stepping stone to writing clean, DRY (Don't Repeat Yourself) Rails code.
Mental Model
Core Idea
Before and after filters are hooks that run shared code automatically around controller actions to keep code clean and organized.
Think of it like...
It's like setting an alarm clock (before filter) to remind you to do something before leaving the house, and turning off the lights (after filter) when you come back home. These tasks happen automatically around your main activity.
┌───────────────┐
│ HTTP Request  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Before Filter │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Controller    │
│ Action        │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ After Filter  │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ HTTP Response │
└───────────────┘
Build-Up - 7 Steps
1
FoundationWhat are filters in Rails
🤔
Concept: Introduce the idea of filters as methods that run before or after controller actions.
In Rails, a controller handles requests by running actions like 'show' or 'edit'. Filters are special methods that run automatically before or after these actions. For example, a before filter can check if a user is logged in before showing a page. An after filter can log information after the action runs. Filters help avoid repeating the same code in every action.
Result
You understand that filters are automatic hooks around controller actions to run shared code.
Understanding filters as automatic hooks helps you see how Rails keeps your controller code clean and DRY.
2
FoundationDefining before and after filters
🤔
Concept: Learn how to write and register before and after filters in a Rails controller.
You define a filter method in your controller, then tell Rails to run it before or after actions using 'before_action' or 'after_action'. For example: class PostsController < ApplicationController before_action :check_login after_action :log_action def show # show post end private def check_login # code to check if user is logged in end def log_action # code to log the action end end This runs 'check_login' before 'show', and 'log_action' after.
Result
You can add methods that run automatically before or after controller actions.
Knowing how to register filters lets you centralize common tasks and avoid repeating code.
3
IntermediateControlling which actions filters run on
🤔Before reading on: do you think filters run on all actions by default or only on specified ones? Commit to your answer.
Concept: Filters can be limited to run only on certain actions or skip some actions using options.
By default, filters run on all actions in the controller. But you can control this with options: before_action :check_login, only: [:edit, :update] This runs 'check_login' only before 'edit' and 'update'. Or you can skip actions: skip_before_action :check_login, only: [:index] This runs the filter on all actions except 'index'. This helps you apply filters precisely where needed.
Result
You can customize filters to run only on specific actions or skip some.
Controlling filter scope prevents unnecessary checks and keeps your app efficient.
4
IntermediateHalting action execution with filters
🤔Before reading on: do you think a before filter can stop the main action from running? Commit to your answer.
Concept: Before filters can stop the controller action from running by redirecting or rendering early.
If a before filter detects a problem, like a user not logged in, it can stop the action by redirecting or rendering a response: before_action :check_login def check_login unless logged_in? redirect_to login_path return end end When the filter redirects, the main action does not run. This is useful for access control.
Result
You can prevent actions from running if conditions are not met, improving security.
Knowing filters can halt actions helps you enforce rules before any sensitive code runs.
5
IntermediateUsing filters with inheritance and multiple controllers
🤔Before reading on: do you think filters defined in a parent controller apply to child controllers automatically? Commit to your answer.
Concept: Filters defined in a parent controller apply to child controllers unless overridden or skipped.
In Rails, controllers often inherit from ApplicationController. Filters defined there run for all child controllers: class ApplicationController < ActionController::Base before_action :check_login end class PostsController < ApplicationController # inherits check_login filter end You can skip or add filters in child controllers to customize behavior. This helps share common logic app-wide.
Result
You understand how filters propagate through controller inheritance.
Knowing filter inheritance helps you organize app-wide checks and customize per controller.
6
AdvancedFilter execution order and stacking filters
🤔Before reading on: do you think multiple filters run in the order they are defined or in reverse? Commit to your answer.
Concept: Multiple filters run in the order they are defined, stacking before and after filters around actions.
If you define several filters, Rails runs before filters in the order declared, then the action, then after filters in reverse order: before_action :first before_action :second def first puts 'first before' end def second puts 'second before' end def show puts 'action' end after_action :third after_action :fourth def third puts 'third after' end def fourth puts 'fourth after' end Output order: first before second before action fourth after third after This stacking lets you build complex workflows.
Result
You can predict and control the order filters run around actions.
Understanding filter order prevents bugs from unexpected execution sequences.
7
ExpertFilters vs Callbacks vs Middleware in Rails
🤔Before reading on: do you think filters, callbacks, and middleware serve the same purpose in Rails? Commit to your answer.
Concept: Filters are controller-level hooks, callbacks are model-level hooks, and middleware runs at the server request level; each serves different layers.
Rails has several hook systems: - Filters run before/after controller actions to manage request handling. - Callbacks run before/after model events like saving or deleting data. - Middleware runs before Rails handles the request, at the server level. Filters are great for web request logic, callbacks for data integrity, and middleware for low-level request processing like compression or authentication. Choosing the right hook depends on where you want to intervene in the app flow.
Result
You can choose the correct hook system for your needs and avoid mixing concerns.
Knowing the differences between filters, callbacks, and middleware helps you architect Rails apps cleanly and avoid confusion.
Under the Hood
Rails filters are implemented as method hooks stored in arrays inside the controller class. When a request comes in, Rails runs the before filters in order by calling each method. If none halt execution, it runs the action method. Then it runs after filters in reverse order. Filters can halt execution by redirecting or rendering early. Internally, Rails uses method chaining and callback chains to manage this flow efficiently.
Why designed this way?
Filters were designed to keep controller actions focused on their main job by moving common pre- and post-processing out. This separation improves code reuse and readability. The chaining design allows multiple filters to stack cleanly and control flow. Alternatives like putting all code inside actions were messy and repetitive, so filters provide a clean, declarative way to manage shared logic.
┌───────────────────────────────┐
│ Controller Class              │
│ ┌─────────────────────────┐ │
│ │ before_filters = [m1,m2]│ │
│ │ after_filters = [m3,m4] │ │
│ └─────────────┬───────────┘ │
└───────────────┼─────────────┘
                │
                ▼
┌───────────────────────────────┐
│ Request Handling Flow          │
│ ┌───────────────┐             │
│ │ Run m1        │             │
│ ├───────────────┤             │
│ │ Run m2        │             │
│ ├───────────────┤             │
│ │ Run action    │             │
│ ├───────────────┤             │
│ │ Run m4        │             │
│ ├───────────────┤             │
│ │ Run m3        │             │
│ └───────────────┘             │
└───────────────────────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Do before filters run after the controller action? Commit to yes or no.
Common Belief:Before filters run after the controller action to clean up.
Tap to reveal reality
Reality:Before filters run before the controller action to prepare or check conditions.
Why it matters:Thinking before filters run after causes confusion about when to place code and can lead to bugs where checks happen too late.
Quick: Do after filters run even if the action redirects early? Commit to yes or no.
Common Belief:After filters always run regardless of redirects or halts.
Tap to reveal reality
Reality:After filters do not run if the action or before filter halts execution by redirecting or rendering early.
Why it matters:Assuming after filters always run can cause missed cleanup or logging, leading to inconsistent app state.
Quick: Can filters modify the parameters passed to the action? Commit to yes or no.
Common Belief:Filters can change the parameters the action receives.
Tap to reveal reality
Reality:Filters can modify instance variables or session data but cannot change the method parameters directly.
Why it matters:Expecting filters to change parameters can lead to design mistakes; parameters should be handled explicitly inside actions.
Quick: Are filters the same as model callbacks? Commit to yes or no.
Common Belief:Filters and model callbacks are the same and interchangeable.
Tap to reveal reality
Reality:Filters run in controllers around actions; callbacks run in models around data events. They serve different purposes.
Why it matters:Confusing these leads to mixing concerns and harder-to-maintain code.
Expert Zone
1
Filters can be skipped or prepended dynamically at runtime, allowing flexible control over execution order.
2
Using filters excessively can lead to hidden side effects; explicit code in actions sometimes improves clarity.
3
Filters do not run for API-only controllers by default unless explicitly added, affecting API design.
When NOT to use
Avoid filters when the logic is very specific to a single action or when it involves complex branching; in such cases, put code directly in the action or use service objects. For cross-cutting concerns at the request level, consider middleware instead.
Production Patterns
In production Rails apps, before filters commonly enforce authentication and authorization, while after filters handle logging or cleanup. Filters are often combined with concerns to share code across controllers. Developers also use filters to set common variables or handle locale settings.
Connections
Middleware
Middleware runs before Rails controllers and can handle similar cross-cutting concerns at a lower level.
Understanding middleware helps you see filters as a higher-level, controller-specific hook, clarifying where to place logic.
Observer Pattern
Filters act like observers that react to controller action events before or after they happen.
Knowing the observer pattern explains how filters decouple shared logic from main actions, improving modularity.
Event Listeners in UI Frameworks
Filters are similar to event listeners that run code before or after user actions in interfaces.
Recognizing this connection helps understand filters as reactive hooks responding to lifecycle events.
Common Pitfalls
#1Running expensive code in before filters for every action unnecessarily.
Wrong approach:before_action :load_heavy_data def load_heavy_data @data = HeavyModel.all end
Correct approach:before_action :load_heavy_data, only: [:show, :edit] def load_heavy_data @data = HeavyModel.all end
Root cause:Not limiting filters to relevant actions causes performance issues by running costly code too often.
#2Assuming after filters run even if before filters redirect early.
Wrong approach:before_action :check_login after_action :log_action def check_login redirect_to login_path unless logged_in? end def log_action logger.info 'Action completed' end
Correct approach:Use around_action or ensure logging in before filter to guarantee execution, or handle logging in middleware.
Root cause:Misunderstanding filter flow causes missed logging or cleanup when redirects happen.
#3Modifying method parameters inside filters expecting changes in action.
Wrong approach:before_action :change_params def change_params params[:id] = 5 end
Correct approach:Modify instance variables or use strong parameters inside actions instead.
Root cause:Misunderstanding that method parameters are immutable in filters leads to ineffective code.
Key Takeaways
Before and after filters run code automatically around controller actions to keep code clean and reusable.
Filters can be customized to run only on specific actions or skipped where not needed, improving efficiency.
Before filters can halt action execution by redirecting or rendering early, useful for access control.
Filters run in a defined order, stacking multiple filters predictably before and after actions.
Filters differ from model callbacks and middleware, each serving distinct layers in a Rails app.

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

  1. Step 1: Understand the role of filters

    Filters in Rails run code around controller actions to modify behavior.
  2. Step 2: Identify the timing of before_action

    before_action runs code before the main action method executes.
  3. Final Answer:

    To run code before a controller action executes -> Option A
  4. 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

  1. Step 1: Recall the modern syntax for after filters

    Rails uses after_action to define code that runs after controller actions.
  2. 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.
  3. Final Answer:

    after_action :log_action -> Option D
  4. 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

  1. Step 1: Understand filter order and effects

    before_action :set_post runs before show, setting @post. after_action :log_post runs after show completes.
  2. 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".
  3. Final Answer:

    The page shows "Hello" and logs "Post viewed: 5" after rendering -> Option A
  4. 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

  1. Step 1: Analyze filter behavior with redirects

    If authenticate_user redirects, the action does not run, but after_action still runs.
  2. Step 2: Understand consequences of after_action after redirect

    Running clear_session after redirect can cause unexpected side effects or errors.
  3. Final Answer:

    The after_action runs even if redirect happens, causing errors -> Option C
  4. 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

  1. Step 1: Identify correct filter type and options

    Use before_action to run code before actions. Use only: to limit to specific actions.
  2. Step 2: Evaluate each option

    before_action :check_admin, only: [:edit, :update] correctly uses before_action with only: [:edit, :update]. before_action :check_admin, except: [:edit, :update] uses except, which excludes those actions. after_action :check_admin, only: [:edit, :update] uses after_action, wrong timing. before_filter :check_admin, only: [:edit, :update] uses deprecated before_filter.
  3. Final Answer:

    before_action :check_admin, only: [:edit, :update] -> Option B
  4. Quick Check:

    Use before_action with only: for specific actions [OK]
Hint: Use before_action with only: to target specific actions [OK]
Common Mistakes:
  • Using except instead of only
  • Using after_action instead of before_action
  • Using deprecated before_filter
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard