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.
