Rails encourages usage of callbacks in controllers to execute common pieces of code before or after an action. A very simple example of this is calling the authenticate_user! method from Devise before every action to make sure that user is authenticated.
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
But what if you want to execute a different piece of code before calling authenticate_user!? I wanted to set a cookie based on whether the request was coming from mobile app or from web before calling authenticate_user!. The most important thing was I wanted to set the cookie only for a particular controller action.
class MagicAuthController < ApplicationController
# Set cookie before authenticate_user! before auth
def auth
end
end
This can be solved by multiple approaches. We can create a separate base controller for MagicAuthController and make sure the cookie is set before calling authenticate_user!
class MagicBaseController < ActionController::Base
before_action :set_cookie, only: [:auth]
before_action :autheticate_user!
end
Though Rails also provides a nifty callback called prepend_before_action. It inserts the callback that is passed to it to the start of the callback chain.
class MagicAuthController < ApplicationController
def auth
end
end
As the MagicAuthController inherits from the ApplicationController the callback chain consists of authenticate_user! as of now.
class MagicAuthController < ApplicationController
prepend_before_action :set_cookie, only: [:auth]
def auth
end
end
This changes the callback chain and now set_cookie is the first callback in the callback chain for the auth action.
Rails also provides other friends of prepend_before_action such as prepend_after_action and prepend_around_action.
It also accepts a block argument.
prepend_before_action only: [:auth] { cookies[:clid] = params[:clid] }
<!--kg-card-end: code--><!--kg-card-begin: hr-->
Want to know more about such tricks and tips from Rails? Subscribe to my newsletter and keep up with Ruby and Rails.
Top comments (0)