Swiftorial Logo
Home
Swift Lessons
AI Tools
Learn More
Career
Resources

Ruby on Rails - Filters in Rails

Introduction

Filters in Rails are methods that run before, after, or around controller actions. They are used to perform tasks such as authentication, authorization, and logging. This guide will cover how to implement filters in Rails controllers effectively.

Key Points:

  • Filters run before, after, or around controller actions.
  • They are useful for tasks like authentication, authorization, and logging.
  • This guide covers the different types of filters and how to implement them in Rails.

Types of Filters

There are three types of filters in Rails:

  • before_action: Runs before the controller action.
  • after_action: Runs after the controller action.
  • around_action: Runs both before and after the controller action.

Using before_action

The before_action filter is used to run code before a controller action. Here is an example:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  before_action :find_article, only: [:show, :edit, :update, :destroy]

  def show
    # @article is already set by the before_action
  end

  def edit
    # @article is already set by the before_action
  end

  def update
    if @article.update(article_params)
      redirect_to @article
    else
      render :edit
    end
  end

  def destroy
    @article.destroy
    redirect_to articles_path
  end

  private

  def find_article
    @article = Article.find(params[:id])
  end

  def article_params
    params.require(:article).permit(:title, :body)
  end
end
                

In this example, the find_article method is called before the show, edit, update, and destroy actions.

Using after_action

The after_action filter is used to run code after a controller action. Here is an example:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  after_action :log_update, only: [:update]

  def update
    @article = Article.find(params[:id])
    if @article.update(article_params)
      redirect_to @article
    else
      render :edit
    end
  end

  private

  def log_update
    Rails.logger.info "Article #{@article.id} was updated."
  end

  def article_params
    params.require(:article).permit(:title, :body)
  end
end
                

In this example, the log_update method is called after the update action to log the update.

Using around_action

The around_action filter is used to run code both before and after a controller action. Here is an example:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  around_action :wrap_in_transaction, only: [:create, :update, :destroy]

  def create
    @article = Article.new(article_params)
    if @article.save
      redirect_to @article
    else
      render :new
    end
  end

  def update
    @article = Article.find(params[:id])
    if @article.update(article_params)
      redirect_to @article
    else
      render :edit
    end
  end

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    redirect_to articles_path
  end

  private

  def wrap_in_transaction
    ActiveRecord::Base.transaction do
      yield
    end
  end

  def article_params
    params.require(:article).permit(:title, :body)
  end
end
                

In this example, the wrap_in_transaction method wraps the create, update, and destroy actions in a database transaction.

Skipping Filters

You can skip filters for specific actions using the skip_before_action, skip_after_action, and skip_around_action methods. Here is an example:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  before_action :authenticate_user!
  skip_before_action :authenticate_user!, only: [:index, :show]

  def index
    @articles = Article.all
  end

  def show
    @article = Article.find(params[:id])
  end

  # Other actions...
end
                

In this example, the authenticate_user! filter is skipped for the index and show actions.

Conditional Filters

You can apply filters conditionally using the :if and :unless options. Here is an example:

# app/controllers/articles_controller.rb
class ArticlesController < ApplicationController
  before_action :check_admin, only: [:destroy], if: :admin?

  def destroy
    @article = Article.find(params[:id])
    @article.destroy
    redirect_to articles_path
  end

  private

  def check_admin
    redirect_to root_path unless current_user.admin?
  end

  def admin?
    current_user.admin?
  end
end
                

In this example, the check_admin filter is only applied to the destroy action if the current user is an admin.

Conclusion

Filters are a powerful feature in Rails that allow you to run code before, after, or around controller actions. By understanding how to use filters effectively, you can perform tasks such as authentication, authorization, and logging in a clean and maintainable way.