lib/spiderfw/controller/dispatcher.rb in spiderfw-0.6.21 vs lib/spiderfw/controller/dispatcher.rb in spiderfw-0.6.22
- old
+ new
@@ -34,18 +34,10 @@
# - the new action
# - the new arguments
def dispatch(method, action='', *arguments)
return nil unless can_dispatch?(method, action)
route = @dispatch_next[action]
- if (!route.obj)
- obj = dispatched_object(route)
- obj.dispatch_previous = self if obj.respond_to?(:dispatch_previous=) && obj != self
- route.obj = obj
- if (route.options[:do])
- obj.instance_exec(*(route.params || []).slice(0, route.options[:do].arity), &route.options[:do])
- end
- end
obj = route.obj
new_arguments = arguments
new_arguments += route.params unless route.options[:remove_params]
return [obj, route.action, new_arguments]
# return obj.send(method, route.action, *(new_arguments))
@@ -65,10 +57,11 @@
# obj.before('news/list')
# obj.before_news
def do_dispatch(method, action='', *arguments)
obj, route_action, new_arguments = dispatch(method, action, *arguments)
return nil unless obj
+ return nil if obj == self && route_action == action # short circuit
meth_action = route_action.length > 0 ? route_action : obj.class.default_action
begin
if (obj.class.dispatch_methods && obj.class.dispatch_methods[method])
obj.class.dispatch_methods[method].each do |dm|
conditions, d_method, params = dm
@@ -108,22 +101,39 @@
end
# Returns the (possibly cached) route for path.
def dispatch_next(path)
@dispatch_next ||= {}
- @dispatch_next[path] ||= get_route(path)
+ @dispatch_next[path] ||= dispatcher_get_route(path)
end
+
+ def dispatcher_get_route(path)
+ route = get_route(path)
+ return route if !route || route.obj
+ obj = dispatched_object(route)
+ obj.dispatch_previous = self if obj.respond_to?(:dispatch_previous=) && obj != self
+ route.obj = obj
+ if route.options[:do]
+ do_args = [route.matched] + (route.params || [])
+ obj.instance_exec(*(do_args).slice(0, route.options[:do].arity), &route.options[:do])
+ end
+ route.obj = obj
+ route
+ end
# Looks in defined routes, and returns the first matching Route for path.
def get_route(path)
path ||= ''
r = routes + self.class.routes
+ if nil_route = self.class.nil_route
+ r << [nil, nil_route[0], nil_route[1]]
+ end
r.each do |route|
try, dest, options = route
action = nil
case try
- when true
+ when true, nil
action = path
matched = ''
when String
test_path = path
if (options[:ignore_case])
@@ -167,10 +177,11 @@
action = dest.to_s
dest = self
end
params ||= []
action.sub!(/^\/+/, '') # no leading slash
+
return Route.new(:path => path, :dest => dest, :action => action, :matched => matched,
:params => params, :options => options)
end
end
return nil
@@ -195,14 +206,16 @@
our_chain = @dispatch_chains && @dispatch_chains[method] ? @dispatch_chains[method] : []
our_chain + self.class.dispatch_chain(method)
end
module ClassMethods
- attr_accessor :default_route, :default_dispatcher
+ attr_accessor :default_route, :default_dispatcher, :nil_route
def add_route(routes, path, dest=nil, options=nil)
- if ( path.is_a? Hash )
+ if path.is_a?(Hash)
path.each {|p,d| add_route(p, d)}
+ elsif path.nil?
+ @nil_route = [dest, options || {}]
else
routes << [path, dest, options || {}]
if path.is_a?(String) && dest.respond_to?(:default_dispatcher=)
dest.default_dispatcher = self
dest.default_route = path