Skip to content

Commit

Permalink
Added before and after filter functionality.
Browse files Browse the repository at this point in the history
  • Loading branch information
mtodd committed Jun 24, 2008
1 parent 4ef3fd4 commit b1c5acf
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 6 deletions.
25 changes: 25 additions & 0 deletions lib/halcyon/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,31 @@ def dispatch(env)
controller._dispatch(action)
end

# def apply_filters(where, controller, action)
# self.logger.debug "Applying #{where.to_s} filters to #{controller.class.to_s}##{action.to_s}"
# if controller.filters[:all].include?(action)
# controller.filters[:all][action].select {|filter| filter[:apply] == where}.each do |filter|
# if filter[:filter_or_block].is_a?(Proc)
# filter[:filter_or_block].call
# else
# controller.send(filter[:filter_or_block])
# end
# end
# end
# if controller.filters[:only].include?(action)
# controller.filters[:only][action].select {|filter| filter[:apply] == where && filter}.each do |filter|
# controller.send(filter[:filter_or_block])
# end
# end
# controller.filters[:except].each do |(filters_not_for_action, filters)|
# unless filters_not_for_action == action
# filters.each do |filter|
# controller.send(filter[:filter_or_block])
# end
# end
# end
# end

# Filters unacceptable requests depending on the configuration of the
# <tt>:allow_from</tt> option.
#
Expand Down
78 changes: 72 additions & 6 deletions lib/halcyon/controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,82 @@ def _dispatch(action)

class << self

# Not implemented.
def before method, &proc
raise NotImplemented.new
# Creates +filters+ accessor method and initializes the +@filters+
# attribute with the necessary structure.
#
def filters
@filters ||= {:before => [], :after => []}
end

# Not implemented.
def after method, &proc
raise NotImplemented.new
# Sets up filters for the method defined in the controllers.
#
# Examples
#
# class Foos < Application
# before :foo do
# #
# end
# after :blah, :only => [:foo]
# def foo
# # the block is called before the method is called
# # and the method is called after the method is called
# end
# private
# def blah
# #
# end
# end
#
# Options
# * +method_or_filter+ either the method to run before
#
def before method_or_filter, options={}, &block
save_filter(:before, method_or_filter, options, block)
end

# See documentation for the +before+ method.
#
def after method_or_filter, options={}, &block
save_filter(:after, method_or_filter, options, block)
end

# Used internally to save the filters, applied when called.
#
def save_filter(where, method_or_filter, options, block)
self.filters[where] << [method_or_filter, options, block]
end

end

# Used internally.
#
# Applies the filters defined by the +before+ and +after+ class methods.
#
# +where+ specifies whether to apply <tt>:before</tt> or <tt>:after</tt>
# filters
# +action+ the routed action (for testing filter applicability)
#
def apply_filters(where, action)
self.class.filters[where].each do |(method_or_filter, options, block)|
if block
block.call(self) if filter_condition_met?(method_or_filter, options, action)
else
send(method_or_filter) if filter_condition_met?(method_or_filter, options, action)
end
end
end

# Used internally.
#
# Tests whether a filter should be run for an action or not.
#
def filter_condition_met?(method_or_filter, options, action)
(
options[:only] and options[:only].include?(action)) or
(options[:except] and !options[:except].include?(action)
) or (
method_or_filter == action
)
end

# Returns the request params and the route params.
Expand Down

0 comments on commit b1c5acf

Please sign in to comment.