Performance: Before and after filters
This affects server response time and perceived page load speed by adding processing steps before or after controller actions.
class PostsController < ApplicationController before_action :load_user, only: [:index, :show, :edit, :update, :destroy] before_action :check_permissions, only: [:edit, :update, :destroy] after_action :log_request, only: [:create, :update, :destroy] def index @posts = Post.all end private def load_user @user = User.find(session[:user_id]) end def check_permissions redirect_to root_path unless @user.admin? end def log_request RequestLogger.log(request) end end
class PostsController < ApplicationController before_action :load_user before_action :check_permissions before_action :log_request def index @posts = Post.all end private def load_user @user = User.find(session[:user_id]) end def check_permissions redirect_to root_path unless @user.admin? end def log_request RequestLogger.log(request) end end
| Pattern | DOM Operations | Reflows | Paint Cost | Verdict |
|---|---|---|---|---|
| Filters run on all actions | N/A (server-side) | N/A | N/A | [X] Bad |
| Filters limited to needed actions | N/A (server-side) | N/A | N/A | [OK] Good |
before_action filter in a Rails controller?before_actionbefore_action runs code before the main action method executes.log_action in a Rails controller?after_action to define code that runs after controller actions.after_filter. after_action :log_action uses correct after_action. before_action :log_action is for before filters. after :log_action is invalid syntax.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
endGET /posts/5 is called, assuming the post with ID 5 has title "Hello"?before_action :set_post runs before show, setting @post. after_action :log_post runs after show completes.show runs, @post is set, so render plain: @post.title outputs "Hello". After rendering, log_post logs "Post viewed: 5".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
endauthenticate_user redirects, the action does not run, but after_action still runs.clear_session after redirect can cause unexpected side effects or errors.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?before_action to run code before actions. Use only: to limit to specific actions.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.Pass the test and this pattern moves unknown