Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails - Call same after_action method from different controllers

Upon sign in, I have my SessionsController run an after_action to reset certain user columns. In another controller, I want to do the same after_action on create and update.

It's easy enough to just copy and paste the same code into both controllers, but I know that one day I'll make a change in one controller and forget to update the other.

Is there any way to call the same method as an after_action from different controllers?

like image 632
Raymond R Avatar asked Feb 23 '16 21:02

Raymond R


1 Answers

There is several ways to do what you want:

  • Option 1: define a method in ApplicationController and call this method with the after_action callback
  • Option 2: define a module in your lib/ folder, include it in the controller and call its method in the after_action callback
  • probably other options

Option 1: a method in ApplicationController

Implementation:

class ApplicationController < ActionController::Base
  # ...

  def clean_user_columns
    raise 'No user connected!' unless current_user.present?
    do_some_stuff
  end

Usage:

class SessionsController < ApplicationController
  after_action :clean_user_columns

Option 2: a module included in the controllers

Implementation:

# file created here: /lib/clean_user_columns_after_action.rb
# you will need to restart your server to see the changes of this file
module CleanUserColumnsAfterAction
  def clean_user_columns
    do_some_stuff
  end
end

Usage:

class SessionController < ApplicationController
  include CleanUserColumnsAfterAction
  after_action :clean_user_columns

Conclusion: In my opinion, the Option #2 is the way to go:

  • option #1 involves that your clean_user_columns is available for every controller of your app but it will only be used when called. Compared to option #2, it saves you one line of code, which is the include CleanCleanUserColumnsAfterAction line.
  • option #2 makes you include the Module where you want to use it instead of giving to every controllers of your app.
  • option #2 can be generalized and be an example for several controller's shared pieces of code, like retrieving records from the DB, executing specific actions (like redirecting if User is not Admin), etc. You can create a folder lib/controllers/ to contain every shared pieces of code of your controllers (if so, don't forget to rename your module to Controllers::CleanUserColumnsAfterAction in the module definition + include statements).
  • options #2 involves a file defined in lib/, which is not reloaded like other files by your development environment. This means before testing your new code on your app, you will need to restart your server.
like image 179
MrYoshiji Avatar answered Nov 05 '22 14:11

MrYoshiji