From c3be207ee8267e2ce8af0f4e168be35fb1d6e5e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 30 May 2010 15:53:14 +0200 Subject: Add :only and :except to controllers MiddlewareStack. This allows you to do the following: class PostsController < ApplicationController use AutheMiddleware, :except => [:index, :show] end --- actionpack/lib/action_controller/metal.rb | 48 ++++++++++++++++++++-- actionpack/lib/action_dispatch/middleware/stack.rb | 8 ++-- 2 files changed, 49 insertions(+), 7 deletions(-) (limited to 'actionpack/lib') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 30aa34d956..775a5002e2 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,6 +1,48 @@ require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/object/blank' +require 'action_dispatch/middleware/stack' module ActionController + # Extend ActionDispatch middleware stack to make it aware of options + # allowing the following syntax in controllers: + # + # class PostsController < ApplicationController + # use AuthenticationMiddleware, :except => [:index, :show] + # end + # + class MiddlewareStack < ActionDispatch::MiddlewareStack #:nodoc: + class Middleware < ActionDispatch::MiddlewareStack::Middleware #:nodoc: + def initialize(klass, *args) + options = args.extract_options! + @only = Array(options.delete(:only)).map(&:to_s) + @except = Array(options.delete(:except)).map(&:to_s) + args << options unless options.empty? + super + end + + def valid?(action) + if @only.present? + @only.include?(action) + elsif @except.present? + !@except.include?(action) + else + true + end + end + end + + def build(action, app=nil, &block) + app ||= block + action = action.to_s + raise "MiddlewareStack#build requires an app" unless app + + reverse.inject(app) do |a, middleware| + middleware.valid?(action) ? + middleware.build(a) : a + end + end + end + # ActionController::Metal provides a way to get a valid Rack application from a controller. # # In AbstractController, dispatching is triggered directly by calling #process on a new controller. @@ -91,10 +133,10 @@ module ActionController end class_attribute :middleware_stack - self.middleware_stack = ActionDispatch::MiddlewareStack.new + self.middleware_stack = ActionController::MiddlewareStack.new def self.inherited(base) - self.middleware_stack = base.middleware_stack.dup + base.middleware_stack = self.middleware_stack.dup super end @@ -120,7 +162,7 @@ module ActionController # ==== Returns # Proc:: A rack application def self.action(name, klass = ActionDispatch::Request) - middleware_stack.build do |env| + middleware_stack.build(name.to_s) do |env| new.dispatch(name, klass.new(env)) end end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 0e5ab507df..e3180dba77 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -55,7 +55,7 @@ module ActionDispatch def insert(index, *args, &block) index = self.index(index) unless index.is_a?(Integer) - middleware = Middleware.new(*args, &block) + middleware = self.class::Middleware.new(*args, &block) super(index, middleware) end @@ -73,7 +73,7 @@ module ActionDispatch end def use(*args, &block) - middleware = Middleware.new(*args, &block) + middleware = self.class::Middleware.new(*args, &block) push(middleware) end @@ -82,8 +82,8 @@ module ActionDispatch "was removed from the middleware stack", caller end - def build(app = nil, &blk) - app ||= blk + def build(app = nil, &block) + app ||= block raise "MiddlewareStack#build requires an app" unless app reverse.inject(app) { |a, e| e.build(a) } end -- cgit v1.2.3