Module: Spider::Dispatcher
- Included in:
- Controller, Router
- Defined in:
- lib/spiderfw/controller/dispatcher.rb
Overview
The includer of this module has to define a method dispatched_object, which must return a child object given the class, the next action, and the route parameters
Defined Under Namespace
Modules: ClassMethods Classes: Route
Instance Attribute Summary collapse
-
#dispatch_previous ⇒ Object
Returns the value of attribute dispatch_previous.
Class Method Summary collapse
Instance Method Summary collapse
- #add_chain_item(method, proc, params) ⇒ Object
-
#can_dispatch?(method, action) ⇒ Boolean
Returns true if there is a route for action, and the routed object responds to method.
-
#dispatch(method, action = '', *arguments) ⇒ Object
Given a method and an action, returns a triplet containing - the object on which to call the method - the new action - the new arguments.
- #dispatch_chain(method) ⇒ Object
-
#dispatch_next(path) ⇒ Object
Returns the (possibly cached) route for path.
-
#do_dispatch(method, action = '', *arguments) ⇒ Object
Dispatches the given method and action: will get an object and new action and arguments from #dispatch, and then call the method on the object, with new action and new arguments as params.
-
#get_route(path) ⇒ Object
Looks in defined routes, and returns the first matching Route for path.
-
#route(path, dest = nil, options = nil) ⇒ Object
Adds one or more routes to the dispatcher.
-
#routes ⇒ Object
Defined routes.
- #run_chain(method, action = '', *params) ⇒ Object
Instance Attribute Details
#dispatch_previous ⇒ Object
Returns the value of attribute dispatch_previous.
6 7 8 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 6 def dispatch_previous @dispatch_previous end |
Class Method Details
.included(klass) ⇒ Object
8 9 10 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 8 def self.included(klass) klass.extend(ClassMethods) end |
Instance Method Details
#add_chain_item(method, proc, params) ⇒ Object
179 180 181 182 183 184 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 179 def add_chain_item(method, proc, params) @dispatch_chains ||= {} @dispatch_chains[method] ||= [] @dispatch_chain_index ||= {} @dispatch_chains[method] << [proc, params] end |
#can_dispatch?(method, action) ⇒ Boolean
Returns true if there is a route for action, and the routed object responds to method.
99 100 101 102 103 104 105 106 107 108 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 99 def can_dispatch?(method, action) d_next = dispatch_next(action) return false unless d_next if (d_next.dest.is_a?(Class)) return false unless d_next.dest.method_defined?(method) else return false unless d_next.dest.respond_to?(method) end return true end |
#dispatch(method, action = '', *arguments) ⇒ Object
Given a method and an action, returns a triplet containing
-
the object on which to call the method
-
the new action
-
the new arguments
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 36 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.[:do]) obj.instance_exec(*(route.params || []).slice(0, route.[:do].arity), &route.[:do]) end end obj = route.obj new_arguments = arguments new_arguments += route.params unless route.[:remove_params] return [obj, route.action, new_arguments] # return obj.send(method, route.action, *(new_arguments)) end |
#dispatch_chain(method) ⇒ Object
194 195 196 197 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 194 def dispatch_chain(method) our_chain = @dispatch_chains && @dispatch_chains[method] ? @dispatch_chains[method] : [] our_chain + self.class.dispatch_chain(method) end |
#dispatch_next(path) ⇒ Object
Returns the (possibly cached) route for path.
111 112 113 114 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 111 def dispatch_next(path) @dispatch_next ||= {} @dispatch_next[path] ||= get_route(path) end |
#do_dispatch(method, action = '', *arguments) ⇒ Object
Dispatches the given method and action: will get an object and new action and arguments from #dispatch, and then call the method on the object, with new action and new arguments as params.
If #dispatch_methods are defined, will call them before calling method. After calling method, will call a method called “#method_Spider::Dispatcher.new_actionnew_action.downcase”, if it exists
Example:
do_dispatch(:before, 'section_b/news/list')
will get obj (in the example, the ‘section_b’ controller) and call
# any method configured in dispatch_methods
obj.before('news/list')
obj.before_news
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 67 def do_dispatch(method, action='', *arguments) obj, route_action, new_arguments = dispatch(method, action, *arguments) return nil unless obj 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 test = check_action(route_action, conditions) test = !test if params[:unless] obj.send(d_method, route_action, *new_arguments) if (test) end end res = obj.send(method, route_action, *(new_arguments)) unless meth_action.empty? meth_action = meth_action[0..-2] if meth_action[-1].chr == '/' meth_action = meth_action.split('/', 2)[0] try_meth = "#{method}_#{meth_action.downcase}" res = obj.send(try_meth, *new_arguments) if obj.respond_to?(try_meth) end return res rescue StandardError, SecurityError => exc if (obj.respond_to?(:try_rescue)) obj.send(:try_rescue, exc) else raise end end end |
#get_route(path) ⇒ Object
Looks in defined routes, and returns the first matching Route for path.
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 117 def get_route(path) path ||= '' r = routes + self.class.routes r.each do |route| try, dest, = route action = nil case try when true action = path matched = '' when String test_path = path if ([:ignore_case]) test_path = path.downcase try.downcase! end if (test_path[0..(try.length-1)] == try) action = path[(try.length)..-1] matched = try end when Regexp action_index = [:action_match] match = try.match(path) if (match) action = action_index ? match[action_index] : match.post_match action = action[0..-2] if action.length > 0 && action[-1].chr == '/' params = match[1..(match.length-1)] matched = match[0] end when Proc res = try.call(path, self) if (res) if (res.is_a?(Array)) action = res[0] params = res[1] matched = res[1] else action = res end end end if (action) if ([:prepend]) action = [:prepend] + action end if (dest.class == Symbol) # route to self new_params = [] new_params << action if action && !action.empty? new_params += (params || []) params = new_params 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 => ) end end return nil end |
#route(path, dest = nil, options = nil) ⇒ Object
Adds one or more routes to the dispatcher. Also accepts an Hash containing path/destination couples
Parameters
- path<String, Regexp>
-
When a string is passed, a path matches if it matches exactly When a regular expression is passed, it is used to match the path
- dest<Spider::Controller, Proc>
-
The route destination
27 28 29 30 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 27 def route(path, dest=nil, =nil) @routes ||= [] self.class.add_route(@routes, path, dest, ) end |
#routes ⇒ Object
Defined routes.
13 14 15 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 13 def routes @routes ||= [] end |
#run_chain(method, action = '', *params) ⇒ Object
186 187 188 189 190 191 192 |
# File 'lib/spiderfw/controller/dispatcher.rb', line 186 def run_chain(method, action='', *params) chain = dispatch_chain(method) return unless chain.length > 0 @dispatch_chain_index ||= {} @dispatch_chain_index[method] = @dispatch_chain_index[method] ? @dispatch_chain_index[method]+1 : 0 instance_eval(&chain[@dispatch_chain_index[method]][0]) if chain[@dispatch_chain_index[method]] end |