rails_legacy_mapper 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gemtest +0 -0
- data/CHANGELOG +3 -0
- data/LICENSE +20 -0
- data/README +25 -0
- data/Rakefile +27 -0
- data/lib/rails_legacy_mapper.rb +23 -0
- data/lib/rails_legacy_mapper/mapper.rb +488 -0
- data/lib/rails_legacy_mapper/route_set_extensions.rb +53 -0
- data/lib/rails_legacy_mapper/version.rb +3 -0
- data/rails_legacy_mapper.gemspec +55 -0
- data/test/fake_controllers.rb +66 -0
- data/test/legacy_route_set_test.rb +578 -0
- data/test/rack_mount_integration_test.rb +310 -0
- data/test/resources_test.rb +1395 -0
- data/test/route_set_test.rb +959 -0
- data/test/test_helper.rb +48 -0
- data/test/uri_reserved_characters_routing_test.rb +54 -0
- metadata +158 -0
data/.gemtest
ADDED
File without changes
|
data/CHANGELOG
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Andrew White
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
== Rails Legacy Mapper
|
2
|
+
This gem provides an extraction of the DeprecatedMapper from Rails 3.0.
|
3
|
+
If you have a legacy application with an old style routes.rb file this
|
4
|
+
allows you to get your application running quickly in Rails 3.1.
|
5
|
+
|
6
|
+
=== Example
|
7
|
+
The trigger for using the legacy mapper is the arity (number of args)
|
8
|
+
of the block passed to draw, e.g:
|
9
|
+
|
10
|
+
LegacyApp::Application.routes.draw do |map|
|
11
|
+
|
12
|
+
map.root :controller => 'pages', :action => 'index'
|
13
|
+
|
14
|
+
map.namespace :admin do |admin|
|
15
|
+
admin.resources :pages
|
16
|
+
end
|
17
|
+
|
18
|
+
map.page '/pages/:id', :controller => 'pages', :action => 'show'
|
19
|
+
|
20
|
+
map.connect '/:controller/:action/:id/'
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
=== License
|
25
|
+
Copyright (c) 2011 Andrew White, released under the MIT license
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/rdoctask'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'rubygems'
|
5
|
+
require 'bundler/setup'
|
6
|
+
|
7
|
+
Bundler::GemHelper.install_tasks
|
8
|
+
|
9
|
+
desc 'Default: run rails_legacy_mapper tests.'
|
10
|
+
task :default => :test
|
11
|
+
|
12
|
+
desc 'Test the sortifiable gem.'
|
13
|
+
Rake::TestTask.new(:test) do |t|
|
14
|
+
t.libs << 'lib'
|
15
|
+
t.libs << 'test'
|
16
|
+
t.pattern = 'test/**/*_test.rb'
|
17
|
+
t.verbose = true
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'Generate documentation for the rails_legacy_mapper gem.'
|
21
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
22
|
+
rdoc.rdoc_dir = 'rdoc'
|
23
|
+
rdoc.title = 'Rails Legacy Mapper'
|
24
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
25
|
+
rdoc.rdoc_files.include('README')
|
26
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
27
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module RailsLegacyMapper
|
2
|
+
# This gem provides an extraction of the DeprecatedMapper from Rails 3.0
|
3
|
+
|
4
|
+
# Returns the current resource action separator - defaults to '/'
|
5
|
+
def self.resource_action_separator
|
6
|
+
@resource_action_separator ||= '/'
|
7
|
+
end
|
8
|
+
|
9
|
+
# Set the resource action separator, e.g:
|
10
|
+
#
|
11
|
+
# # config/initializers/rails_legacy_mapper.rb
|
12
|
+
# RailsLegacyMapper.resource_action_separator = ';'
|
13
|
+
def self.resource_action_separator=(value)
|
14
|
+
@resource_action_separator = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require 'rails_legacy_mapper/mapper'
|
19
|
+
require 'rails_legacy_mapper/route_set_extensions'
|
20
|
+
require 'rails_legacy_mapper/version'
|
21
|
+
require 'action_dispatch'
|
22
|
+
|
23
|
+
ActionDispatch::Routing::RouteSet.send(:include, RailsLegacyMapper::RouteSetExtensions)
|
@@ -0,0 +1,488 @@
|
|
1
|
+
require 'active_support/core_ext/array/wrap'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
3
|
+
require 'active_support/core_ext/object/with_options'
|
4
|
+
require 'active_support/core_ext/object/try'
|
5
|
+
require 'active_support/inflector'
|
6
|
+
|
7
|
+
module RailsLegacyMapper
|
8
|
+
class Mapper #:nodoc:
|
9
|
+
def initialize(set) #:nodoc:
|
10
|
+
@set = set
|
11
|
+
end
|
12
|
+
|
13
|
+
def connect(path, options = {})
|
14
|
+
options = options.dup
|
15
|
+
|
16
|
+
if conditions = options.delete(:conditions)
|
17
|
+
conditions = conditions.dup
|
18
|
+
method = Array.wrap(conditions.delete(:method))
|
19
|
+
method.map! { |m|
|
20
|
+
if m == :head
|
21
|
+
raise ArgumentError, "HTTP method HEAD is invalid in route conditions. Rails processes HEAD requests the same as GETs, returning just the response headers"
|
22
|
+
end
|
23
|
+
|
24
|
+
unless ActionDispatch::Routing::HTTP_METHODS.include?(m)
|
25
|
+
raise ArgumentError, "Invalid HTTP method specified in route conditions"
|
26
|
+
end
|
27
|
+
|
28
|
+
m.to_s.dasherize.upcase
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
path_prefix = options.delete(:path_prefix)
|
33
|
+
name_prefix = options.delete(:name_prefix)
|
34
|
+
namespace = options.delete(:namespace)
|
35
|
+
|
36
|
+
name = options.delete(:_name)
|
37
|
+
name = "#{name_prefix}#{name}" if name_prefix
|
38
|
+
|
39
|
+
requirements = options.delete(:requirements) || {}
|
40
|
+
defaults = options.delete(:defaults) || {}
|
41
|
+
options.each do |k, v|
|
42
|
+
if v.is_a?(Regexp)
|
43
|
+
if value = options.delete(k)
|
44
|
+
requirements[k.to_sym] = value
|
45
|
+
end
|
46
|
+
else
|
47
|
+
value = options.delete(k)
|
48
|
+
defaults[k.to_sym] = value.is_a?(Symbol) ? value : value.to_param
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
requirements.each do |_, requirement|
|
53
|
+
if requirement.source =~ %r{\A(\\A|\^)|(\\Z|\\z|\$)\Z}
|
54
|
+
raise ArgumentError, "Regexp anchor characters are not allowed in routing requirements: #{requirement.inspect}"
|
55
|
+
end
|
56
|
+
if requirement.multiline?
|
57
|
+
raise ArgumentError, "Regexp multiline option not allowed in routing requirements: #{requirement.inspect}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
requirements[:controller] ||= @set.controller_constraints
|
62
|
+
|
63
|
+
if defaults[:controller]
|
64
|
+
defaults[:action] ||= 'index'
|
65
|
+
defaults[:controller] = defaults[:controller].to_s
|
66
|
+
defaults[:controller] = "#{namespace}#{defaults[:controller]}" if namespace
|
67
|
+
end
|
68
|
+
|
69
|
+
if defaults[:action]
|
70
|
+
defaults[:action] = defaults[:action].to_s
|
71
|
+
end
|
72
|
+
|
73
|
+
if path.is_a?(String)
|
74
|
+
path = "#{path_prefix}/#{path}" if path_prefix
|
75
|
+
path = path.gsub('.:format', '(.:format)')
|
76
|
+
path = optionalize_trailing_dynamic_segments(path, requirements, defaults)
|
77
|
+
glob = $1.to_sym if path =~ /\/\*(\w+)$/
|
78
|
+
path = ::Rack::Mount::Utils.normalize_path(path)
|
79
|
+
|
80
|
+
if glob && !defaults[glob].blank?
|
81
|
+
raise ActionController::RoutingError, "paths cannot have non-empty default values"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
app = ActionDispatch::Routing::RouteSet::Dispatcher.new(:defaults => defaults, :glob => glob)
|
86
|
+
|
87
|
+
conditions = {}
|
88
|
+
conditions[:request_method] = method if method && !method.empty?
|
89
|
+
conditions[:path_info] = path if path
|
90
|
+
|
91
|
+
@set.add_route(app, conditions, requirements, defaults, name)
|
92
|
+
end
|
93
|
+
|
94
|
+
def optionalize_trailing_dynamic_segments(path, requirements, defaults) #:nodoc:
|
95
|
+
path = (path =~ /^\//) ? path.dup : "/#{path}"
|
96
|
+
optional, segments = true, []
|
97
|
+
|
98
|
+
required_segments = requirements.keys
|
99
|
+
required_segments -= defaults.keys.compact
|
100
|
+
|
101
|
+
old_segments = path.split('/')
|
102
|
+
old_segments.shift
|
103
|
+
length = old_segments.length
|
104
|
+
|
105
|
+
old_segments.reverse.each_with_index do |segment, index|
|
106
|
+
required_segments.each do |required|
|
107
|
+
if segment =~ /#{required}/
|
108
|
+
optional = false
|
109
|
+
break
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
if optional
|
114
|
+
if segment == ":id" && segments.include?(":action")
|
115
|
+
optional = false
|
116
|
+
elsif segment == ":controller" || segment == ":action" || segment == ":id"
|
117
|
+
# Ignore
|
118
|
+
elsif !(segment =~ /^:\w+$/) &&
|
119
|
+
!(segment =~ /^:\w+\(\.:format\)$/)
|
120
|
+
optional = false
|
121
|
+
elsif segment =~ /^:(\w+)$/
|
122
|
+
if defaults.has_key?($1.to_sym)
|
123
|
+
defaults.delete($1.to_sym) if defaults[$1.to_sym].nil?
|
124
|
+
else
|
125
|
+
optional = false
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
if optional && index < length - 1
|
131
|
+
segments.unshift('(/', segment)
|
132
|
+
segments.push(')')
|
133
|
+
elsif optional
|
134
|
+
segments.unshift('/(', segment)
|
135
|
+
segments.push(')')
|
136
|
+
else
|
137
|
+
segments.unshift('/', segment)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
141
|
+
segments.join
|
142
|
+
end
|
143
|
+
private :optionalize_trailing_dynamic_segments
|
144
|
+
|
145
|
+
# Creates a named route called "root" for matching the root level request.
|
146
|
+
def root(options = {})
|
147
|
+
if options.is_a?(Symbol)
|
148
|
+
if source_route = @set.named_routes.routes[options]
|
149
|
+
options = source_route.defaults.merge({ :conditions => source_route.conditions })
|
150
|
+
end
|
151
|
+
end
|
152
|
+
named_route("root", '', options)
|
153
|
+
end
|
154
|
+
|
155
|
+
def named_route(name, path, options = {}) #:nodoc:
|
156
|
+
options[:_name] = name
|
157
|
+
connect(path, options)
|
158
|
+
end
|
159
|
+
|
160
|
+
def namespace(name, options = {}, &block)
|
161
|
+
if options[:namespace]
|
162
|
+
with_options({:path_prefix => "#{options.delete(:path_prefix)}/#{name}", :name_prefix => "#{options.delete(:name_prefix)}#{name}_", :namespace => "#{options.delete(:namespace)}#{name}/" }.merge(options), &block)
|
163
|
+
else
|
164
|
+
with_options({:path_prefix => name, :name_prefix => "#{name}_", :namespace => "#{name}/" }.merge(options), &block)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
def method_missing(route_name, *args, &proc) #:nodoc:
|
169
|
+
super unless args.length >= 1 && proc.nil?
|
170
|
+
named_route(route_name, *args)
|
171
|
+
end
|
172
|
+
|
173
|
+
INHERITABLE_OPTIONS = :namespace, :shallow
|
174
|
+
|
175
|
+
class Resource #:nodoc:
|
176
|
+
DEFAULT_ACTIONS = :index, :create, :new, :edit, :show, :update, :destroy
|
177
|
+
|
178
|
+
attr_reader :collection_methods, :member_methods, :new_methods
|
179
|
+
attr_reader :path_prefix, :name_prefix, :path_segment
|
180
|
+
attr_reader :plural, :singular
|
181
|
+
attr_reader :options, :defaults
|
182
|
+
|
183
|
+
def initialize(entities, options, defaults)
|
184
|
+
@plural ||= entities
|
185
|
+
@singular ||= options[:singular] || plural.to_s.singularize
|
186
|
+
@path_segment = options.delete(:as) || @plural
|
187
|
+
|
188
|
+
@options = options
|
189
|
+
@defaults = defaults
|
190
|
+
|
191
|
+
arrange_actions
|
192
|
+
add_default_actions
|
193
|
+
set_allowed_actions
|
194
|
+
set_prefixes
|
195
|
+
end
|
196
|
+
|
197
|
+
def controller
|
198
|
+
@controller ||= "#{options[:namespace]}#{(options[:controller] || plural).to_s}"
|
199
|
+
end
|
200
|
+
|
201
|
+
def requirements(with_id = false)
|
202
|
+
@requirements ||= @options[:requirements] || {}
|
203
|
+
@id_requirement ||= { :id => @requirements.delete(:id) || /[^#{ActionDispatch::Routing::SEPARATORS.join}]+/ }
|
204
|
+
|
205
|
+
with_id ? @requirements.merge(@id_requirement) : @requirements
|
206
|
+
end
|
207
|
+
|
208
|
+
def conditions
|
209
|
+
@conditions ||= @options[:conditions] || {}
|
210
|
+
end
|
211
|
+
|
212
|
+
def path
|
213
|
+
@path ||= "#{path_prefix}/#{path_segment}"
|
214
|
+
end
|
215
|
+
|
216
|
+
def new_path
|
217
|
+
new_action = self.options[:path_names][:new] if self.options[:path_names]
|
218
|
+
new_action ||= self.defaults[:path_names][:new]
|
219
|
+
@new_path ||= "#{path}/#{new_action}"
|
220
|
+
end
|
221
|
+
|
222
|
+
def shallow_path_prefix
|
223
|
+
@shallow_path_prefix ||= @options[:shallow] ? @options[:namespace].try(:sub, /\/$/, '') : path_prefix
|
224
|
+
end
|
225
|
+
|
226
|
+
def member_path
|
227
|
+
@member_path ||= "#{shallow_path_prefix}/#{path_segment}/:id"
|
228
|
+
end
|
229
|
+
|
230
|
+
def nesting_path_prefix
|
231
|
+
@nesting_path_prefix ||= "#{shallow_path_prefix}/#{path_segment}/:#{singular}_id"
|
232
|
+
end
|
233
|
+
|
234
|
+
def shallow_name_prefix
|
235
|
+
@shallow_name_prefix ||= @options[:shallow] ? @options[:namespace].try(:gsub, /\//, '_') : name_prefix
|
236
|
+
end
|
237
|
+
|
238
|
+
def nesting_name_prefix
|
239
|
+
"#{shallow_name_prefix}#{singular}_"
|
240
|
+
end
|
241
|
+
|
242
|
+
def action_separator
|
243
|
+
@action_separator ||= RailsLegacyMapper.resource_action_separator
|
244
|
+
end
|
245
|
+
|
246
|
+
def uncountable?
|
247
|
+
@singular.to_s == @plural.to_s
|
248
|
+
end
|
249
|
+
|
250
|
+
def has_action?(action)
|
251
|
+
!DEFAULT_ACTIONS.include?(action) || action_allowed?(action)
|
252
|
+
end
|
253
|
+
|
254
|
+
protected
|
255
|
+
def arrange_actions
|
256
|
+
@collection_methods = arrange_actions_by_methods(options.delete(:collection))
|
257
|
+
@member_methods = arrange_actions_by_methods(options.delete(:member))
|
258
|
+
@new_methods = arrange_actions_by_methods(options.delete(:new))
|
259
|
+
end
|
260
|
+
|
261
|
+
def add_default_actions
|
262
|
+
add_default_action(member_methods, :get, :edit)
|
263
|
+
add_default_action(new_methods, :get, :new)
|
264
|
+
end
|
265
|
+
|
266
|
+
def set_allowed_actions
|
267
|
+
only, except = @options.values_at(:only, :except)
|
268
|
+
@allowed_actions ||= {}
|
269
|
+
|
270
|
+
if only == :all || except == :none
|
271
|
+
only = nil
|
272
|
+
except = []
|
273
|
+
elsif only == :none || except == :all
|
274
|
+
only = []
|
275
|
+
except = nil
|
276
|
+
end
|
277
|
+
|
278
|
+
if only
|
279
|
+
@allowed_actions[:only] = Array(only).map {|a| a.to_sym }
|
280
|
+
elsif except
|
281
|
+
@allowed_actions[:except] = Array(except).map {|a| a.to_sym }
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
def action_allowed?(action)
|
286
|
+
only, except = @allowed_actions.values_at(:only, :except)
|
287
|
+
(!only || only.include?(action)) && (!except || !except.include?(action))
|
288
|
+
end
|
289
|
+
|
290
|
+
def set_prefixes
|
291
|
+
@path_prefix = options.delete(:path_prefix)
|
292
|
+
@name_prefix = options.delete(:name_prefix)
|
293
|
+
end
|
294
|
+
|
295
|
+
def arrange_actions_by_methods(actions)
|
296
|
+
(actions || {}).inject({}) do |flipped_hash, (key, value)|
|
297
|
+
(flipped_hash[value] ||= []) << key
|
298
|
+
flipped_hash
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
def add_default_action(collection, method, action)
|
303
|
+
(collection[method] ||= []).unshift(action)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
class SingletonResource < Resource #:nodoc:
|
308
|
+
def initialize(entity, options, defaults)
|
309
|
+
@singular = @plural = entity
|
310
|
+
options[:controller] ||= @singular.to_s.pluralize
|
311
|
+
super
|
312
|
+
end
|
313
|
+
|
314
|
+
alias_method :shallow_path_prefix, :path_prefix
|
315
|
+
alias_method :shallow_name_prefix, :name_prefix
|
316
|
+
alias_method :member_path, :path
|
317
|
+
alias_method :nesting_path_prefix, :path
|
318
|
+
end
|
319
|
+
|
320
|
+
def resources(*entities, &block)
|
321
|
+
options = entities.extract_options!
|
322
|
+
entities.each { |entity| map_resource(entity, options.dup, &block) }
|
323
|
+
end
|
324
|
+
|
325
|
+
def resource(*entities, &block)
|
326
|
+
options = entities.extract_options!
|
327
|
+
entities.each { |entity| map_singleton_resource(entity, options.dup, &block) }
|
328
|
+
end
|
329
|
+
|
330
|
+
private
|
331
|
+
def map_resource(entities, options = {}, &block)
|
332
|
+
resource = Resource.new(entities, options, :path_names => @set.resources_path_names)
|
333
|
+
|
334
|
+
with_options :controller => resource.controller do |map|
|
335
|
+
map_associations(resource, options)
|
336
|
+
|
337
|
+
if block_given?
|
338
|
+
with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
|
339
|
+
end
|
340
|
+
|
341
|
+
map_collection_actions(map, resource)
|
342
|
+
map_default_collection_actions(map, resource)
|
343
|
+
map_new_actions(map, resource)
|
344
|
+
map_member_actions(map, resource)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
def map_singleton_resource(entities, options = {}, &block)
|
349
|
+
resource = SingletonResource.new(entities, options, :path_names => @set.resources_path_names)
|
350
|
+
|
351
|
+
with_options :controller => resource.controller do |map|
|
352
|
+
map_associations(resource, options)
|
353
|
+
|
354
|
+
if block_given?
|
355
|
+
with_options(options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix), &block)
|
356
|
+
end
|
357
|
+
|
358
|
+
map_collection_actions(map, resource)
|
359
|
+
map_new_actions(map, resource)
|
360
|
+
map_member_actions(map, resource)
|
361
|
+
map_default_singleton_actions(map, resource)
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
def map_associations(resource, options)
|
366
|
+
map_has_many_associations(resource, options.delete(:has_many), options) if options[:has_many]
|
367
|
+
|
368
|
+
path_prefix = "#{options.delete(:path_prefix)}#{resource.nesting_path_prefix}"
|
369
|
+
name_prefix = "#{options.delete(:name_prefix)}#{resource.nesting_name_prefix}"
|
370
|
+
|
371
|
+
Array(options[:has_one]).each do |association|
|
372
|
+
resource(association, options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => path_prefix, :name_prefix => name_prefix))
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
def map_has_many_associations(resource, associations, options)
|
377
|
+
case associations
|
378
|
+
when Hash
|
379
|
+
associations.each do |association,has_many|
|
380
|
+
map_has_many_associations(resource, association, options.merge(:has_many => has_many))
|
381
|
+
end
|
382
|
+
when Array
|
383
|
+
associations.each do |association|
|
384
|
+
map_has_many_associations(resource, association, options)
|
385
|
+
end
|
386
|
+
when Symbol, String
|
387
|
+
resources(associations, options.slice(*INHERITABLE_OPTIONS).merge(:path_prefix => resource.nesting_path_prefix, :name_prefix => resource.nesting_name_prefix, :has_many => options[:has_many]))
|
388
|
+
else
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
def map_collection_actions(map, resource)
|
393
|
+
resource.collection_methods.each do |method, actions|
|
394
|
+
actions.each do |action|
|
395
|
+
[method].flatten.each do |m|
|
396
|
+
action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
|
397
|
+
action_path ||= action
|
398
|
+
|
399
|
+
map_resource_routes(map, resource, action, "#{resource.path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.name_prefix}#{resource.plural}", m)
|
400
|
+
end
|
401
|
+
end
|
402
|
+
end
|
403
|
+
end
|
404
|
+
|
405
|
+
def map_default_collection_actions(map, resource)
|
406
|
+
index_route_name = "#{resource.name_prefix}#{resource.plural}"
|
407
|
+
|
408
|
+
if resource.uncountable?
|
409
|
+
index_route_name << "_index"
|
410
|
+
end
|
411
|
+
|
412
|
+
map_resource_routes(map, resource, :index, resource.path, index_route_name)
|
413
|
+
map_resource_routes(map, resource, :create, resource.path, index_route_name)
|
414
|
+
end
|
415
|
+
|
416
|
+
def map_default_singleton_actions(map, resource)
|
417
|
+
map_resource_routes(map, resource, :create, resource.path, "#{resource.shallow_name_prefix}#{resource.singular}")
|
418
|
+
end
|
419
|
+
|
420
|
+
def map_new_actions(map, resource)
|
421
|
+
resource.new_methods.each do |method, actions|
|
422
|
+
actions.each do |action|
|
423
|
+
route_path = resource.new_path
|
424
|
+
route_name = "new_#{resource.name_prefix}#{resource.singular}"
|
425
|
+
|
426
|
+
unless action == :new
|
427
|
+
route_path = "#{route_path}#{resource.action_separator}#{action}"
|
428
|
+
route_name = "#{action}_#{route_name}"
|
429
|
+
end
|
430
|
+
|
431
|
+
map_resource_routes(map, resource, action, route_path, route_name, method)
|
432
|
+
end
|
433
|
+
end
|
434
|
+
end
|
435
|
+
|
436
|
+
def map_member_actions(map, resource)
|
437
|
+
resource.member_methods.each do |method, actions|
|
438
|
+
actions.each do |action|
|
439
|
+
[method].flatten.each do |m|
|
440
|
+
action_path = resource.options[:path_names][action] if resource.options[:path_names].is_a?(Hash)
|
441
|
+
action_path ||= @set.resources_path_names[action] || action
|
442
|
+
|
443
|
+
map_resource_routes(map, resource, action, "#{resource.member_path}#{resource.action_separator}#{action_path}", "#{action}_#{resource.shallow_name_prefix}#{resource.singular}", m, { :force_id => true })
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
route_path = "#{resource.shallow_name_prefix}#{resource.singular}"
|
449
|
+
map_resource_routes(map, resource, :show, resource.member_path, route_path)
|
450
|
+
map_resource_routes(map, resource, :update, resource.member_path, route_path)
|
451
|
+
map_resource_routes(map, resource, :destroy, resource.member_path, route_path)
|
452
|
+
end
|
453
|
+
|
454
|
+
def map_resource_routes(map, resource, action, route_path, route_name = nil, method = nil, resource_options = {} )
|
455
|
+
if resource.has_action?(action)
|
456
|
+
action_options = action_options_for(action, resource, method, resource_options)
|
457
|
+
formatted_route_path = "#{route_path}.:format"
|
458
|
+
|
459
|
+
if route_name && @set.named_routes[route_name.to_sym].nil?
|
460
|
+
map.named_route(route_name, formatted_route_path, action_options)
|
461
|
+
else
|
462
|
+
map.connect(formatted_route_path, action_options)
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
def add_conditions_for(conditions, method)
|
468
|
+
{:conditions => conditions.dup}.tap do |options|
|
469
|
+
options[:conditions][:method] = method unless method == :any
|
470
|
+
end
|
471
|
+
end
|
472
|
+
|
473
|
+
def action_options_for(action, resource, method = nil, resource_options = {})
|
474
|
+
default_options = { :action => action.to_s }
|
475
|
+
require_id = !resource.kind_of?(SingletonResource)
|
476
|
+
force_id = resource_options[:force_id] && !resource.kind_of?(SingletonResource)
|
477
|
+
|
478
|
+
case default_options[:action]
|
479
|
+
when "index", "new"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements)
|
480
|
+
when "create"; default_options.merge(add_conditions_for(resource.conditions, method || :post)).merge(resource.requirements)
|
481
|
+
when "show", "edit"; default_options.merge(add_conditions_for(resource.conditions, method || :get)).merge(resource.requirements(require_id))
|
482
|
+
when "update"; default_options.merge(add_conditions_for(resource.conditions, method || :put)).merge(resource.requirements(require_id))
|
483
|
+
when "destroy"; default_options.merge(add_conditions_for(resource.conditions, method || :delete)).merge(resource.requirements(require_id))
|
484
|
+
else default_options.merge(add_conditions_for(resource.conditions, method)).merge(resource.requirements(force_id))
|
485
|
+
end
|
486
|
+
end
|
487
|
+
end
|
488
|
+
end
|