Where to put a before_filter shared between multip

2020-02-28 04:12发布

问题:

I have multiple controllers that all use an identical before_filter. In the interests of keeping things dry, where should this method live so that all the controllers can use it? A module doesn't seem like the right place, though I'm not sure why. I can't put it in a base class as the controllers already have different superclasses.

回答1:

How about putting your before_filter and method in a module and including it in each of the controllers. I'd put this file in the lib folder.

module MyFunctions

  def self.included(base)
    base.before_filter :my_before_filter
  end

  def my_before_filter
    Rails.logger.info "********** YEA I WAS CALLED ***************"
  end
end

Then in your controller, all you would have to do is

class MyController < ActionController::Base
  include MyFunctions
end

Finally, I would ensure that lib is autoloaded. Open config/application.rb and add the following to the class for your application.

config.autoload_paths += %W(#{config.root}/lib)


回答2:

Something like this can be done.

Class CommonController < ApplicationController
  # before_filter goes here
end

Class MyController < CommonController
end

class MyOtherController < CommonController
end


回答3:

Place the before_filter in the shared superclass of your controllers. If you have to go so far up the inheritance chain that this winds up being ApplicationController, and you are forced to apply the before_filter to some controllers it shouldn't apply to, you should use skip_before_filter in those specific controllers:

class ApplicationController < ActionController::Base
  before_filter :require_user
end

# Login controller shouldn't require a user
class LoginController < ApplicationController
  skip_before_filter :require_user
end

# Posts requires a user
class PostsController < ApplicationController

end

# Comments requires a user
class CommentsController < ApplicationController

end


回答4:

If it is common to all controllers, you may put it in the application controller. If not, you can create a new controller and make it the superclass of them all and put the code in it.