josevalim-inherited_resources 0.7.3 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +6 -0
- data/README +8 -1
- data/lib/inherited_resources.rb +23 -0
- data/lib/inherited_resources/actions.rb +96 -0
- data/lib/inherited_resources/base.rb +6 -110
- data/lib/inherited_resources/base_helpers.rb +12 -16
- data/lib/inherited_resources/class_methods.rb +20 -25
- data/lib/inherited_resources/singleton_helpers.rb +2 -2
- data/lib/inherited_resources/url_helpers.rb +79 -122
- data/test/aliases_test.rb +2 -1
- data/test/base_test.rb +4 -1
- data/test/class_methods_test.rb +3 -3
- data/test/redirect_to_test.rb +22 -53
- metadata +3 -2
data/CHANGELOG
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
# Version 0.8
|
2
|
+
|
3
|
+
* Allow InheritedResources to be called without inheritance.
|
4
|
+
* Ensure that controllers that inherit from a controller with InheritedResources
|
5
|
+
works properly.
|
6
|
+
|
1
7
|
# Version 0.7
|
2
8
|
|
3
9
|
* Allow procs as default value in has scope to be able to use values from session, for example.
|
data/README
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Inherited Resources
|
2
2
|
License: MIT
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.8.0
|
4
4
|
|
5
5
|
You can also read this README in pretty html at the GitHub project Wiki page:
|
6
6
|
|
@@ -93,6 +93,13 @@ In your views, you will get the following helpers:
|
|
93
93
|
As you might expect, collection (@projects instance variable) is only available
|
94
94
|
on index actions.
|
95
95
|
|
96
|
+
If for some reason you cannot inherit from InheritedResources::Base, you can
|
97
|
+
call inherit_resources or resource_controller in your controller class scope:
|
98
|
+
|
99
|
+
class AccountsController < ApplicationController
|
100
|
+
inherit_resources # or resource_controller
|
101
|
+
end
|
102
|
+
|
96
103
|
Overwriting defaults
|
97
104
|
--------------------
|
98
105
|
|
data/lib/inherited_resources.rb
CHANGED
@@ -4,3 +4,26 @@
|
|
4
4
|
require File.join(File.dirname(__FILE__), 'inherited_resources', 'respond_to')
|
5
5
|
|
6
6
|
module InheritedResources; end
|
7
|
+
|
8
|
+
class ActionController::Base
|
9
|
+
class << self
|
10
|
+
# If you cannot inherit from InheritedResources::Base you can call
|
11
|
+
# inherit_resource or resource_controller in your controller to have all
|
12
|
+
# the required modules and funcionality included.
|
13
|
+
#
|
14
|
+
def inherit_resources
|
15
|
+
include InheritedResources::Actions
|
16
|
+
include InheritedResources::BaseHelpers
|
17
|
+
extend InheritedResources::ClassMethods
|
18
|
+
extend InheritedResources::UrlHelpers
|
19
|
+
|
20
|
+
helper_method :collection_url, :collection_path, :resource_url, :resource_path,
|
21
|
+
:new_resource_url, :new_resource_path, :edit_resource_url, :edit_resource_path,
|
22
|
+
:resource, :collection, :resource_class
|
23
|
+
|
24
|
+
initialize_resources_class_accessors!
|
25
|
+
create_resources_url_helpers!
|
26
|
+
end
|
27
|
+
alias :resource_controller :inherit_resources
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module InheritedResources
|
2
|
+
RESOURCES_ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?(:RESOURCES_ACTIONS)
|
3
|
+
|
4
|
+
# Holds all default actions for InheritedResouces.
|
5
|
+
module Actions
|
6
|
+
|
7
|
+
# GET /resources
|
8
|
+
def index(&block)
|
9
|
+
respond_to(:with => collection, &block)
|
10
|
+
end
|
11
|
+
alias :index! :index
|
12
|
+
|
13
|
+
# GET /resources/1
|
14
|
+
def show(&block)
|
15
|
+
respond_to(:with => resource, &block)
|
16
|
+
end
|
17
|
+
alias :show! :show
|
18
|
+
|
19
|
+
# GET /resources/new
|
20
|
+
def new(&block)
|
21
|
+
respond_to(:with => build_resource, &block)
|
22
|
+
end
|
23
|
+
alias :new! :new
|
24
|
+
|
25
|
+
# GET /resources/1/edit
|
26
|
+
def edit(&block)
|
27
|
+
respond_to(:with => resource, &block)
|
28
|
+
end
|
29
|
+
alias :edit! :edit
|
30
|
+
|
31
|
+
# POST /resources
|
32
|
+
def create(redirect_url=nil, &block)
|
33
|
+
object = build_resource(params[resource_instance_name])
|
34
|
+
respond_block, redirect_block = select_block_by_arity(block)
|
35
|
+
|
36
|
+
if object.save
|
37
|
+
set_flash_message!(:notice, '{{resource_name}} was successfully created.')
|
38
|
+
options = { :with => object, :status => :created, :location => (resource_url rescue nil) }
|
39
|
+
|
40
|
+
respond_to_with_dual_blocks(true, respond_block, options) do |format|
|
41
|
+
format.html { redirect_to(redirect_block ? redirect_block.call : resource_url) }
|
42
|
+
end
|
43
|
+
else
|
44
|
+
set_flash_message!(:error)
|
45
|
+
options = { :with => object.errors, :status => :unprocessable_entity }
|
46
|
+
|
47
|
+
respond_to_with_dual_blocks(false, respond_block, options) do |format|
|
48
|
+
format.html { render :action => 'new' }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
alias :create! :create
|
53
|
+
|
54
|
+
# PUT /resources/1
|
55
|
+
def update(redirect_url=nil, &block)
|
56
|
+
object = resource
|
57
|
+
respond_block, redirect_block = select_block_by_arity(block)
|
58
|
+
|
59
|
+
if object.update_attributes(params[resource_instance_name])
|
60
|
+
set_flash_message!(:notice, '{{resource_name}} was successfully updated.')
|
61
|
+
|
62
|
+
respond_to_with_dual_blocks(true, block) do |format|
|
63
|
+
format.html { redirect_to(redirect_block ? redirect_block.call : resource_url) }
|
64
|
+
format.all { head :ok }
|
65
|
+
end
|
66
|
+
else
|
67
|
+
set_flash_message!(:error)
|
68
|
+
|
69
|
+
options = { :with => object.errors, :status => :unprocessable_entity }
|
70
|
+
|
71
|
+
respond_to_with_dual_blocks(false, block, options) do |format|
|
72
|
+
format.html { render :action => 'edit' }
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
alias :update! :update
|
77
|
+
|
78
|
+
# DELETE /resources/1
|
79
|
+
def destroy(redirect_url=nil, &block)
|
80
|
+
resource.destroy
|
81
|
+
respond_block, redirect_block = select_block_by_arity(block)
|
82
|
+
|
83
|
+
set_flash_message!(:notice, '{{resource_name}} was successfully destroyed.')
|
84
|
+
|
85
|
+
respond_to_with_dual_blocks(nil, respond_block) do |format|
|
86
|
+
format.html { redirect_to(redirect_block ? redirect_block.call : collection_url) }
|
87
|
+
format.all { head :ok }
|
88
|
+
end
|
89
|
+
end
|
90
|
+
alias :destroy! :destroy
|
91
|
+
|
92
|
+
# Make aliases protected
|
93
|
+
protected :index!, :show!, :new!, :create!, :edit!, :update!, :destroy!
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -1,13 +1,4 @@
|
|
1
|
-
# Whenever Base is required, we eager load the base files. belongs_to, polymorphic
|
2
|
-
# and singleton helpers are loaded on demand.
|
3
|
-
require File.dirname(__FILE__) + '/base_helpers.rb'
|
4
|
-
require File.dirname(__FILE__) + '/class_methods.rb'
|
5
|
-
require File.dirname(__FILE__) + '/dumb_responder.rb'
|
6
|
-
require File.dirname(__FILE__) + '/url_helpers.rb'
|
7
|
-
|
8
1
|
module InheritedResources
|
9
|
-
RESOURCES_ACTIONS = [ :index, :show, :new, :edit, :create, :update, :destroy ] unless self.const_defined?(:RESOURCES_ACTIONS)
|
10
|
-
|
11
2
|
# = Base
|
12
3
|
#
|
13
4
|
# This is the base class that holds all actions. If you see the code for each
|
@@ -20,114 +11,19 @@ module InheritedResources
|
|
20
11
|
class Base < ::ApplicationController
|
21
12
|
unloadable
|
22
13
|
|
14
|
+
include InheritedResources::Actions
|
23
15
|
include InheritedResources::BaseHelpers
|
24
|
-
extend
|
16
|
+
extend InheritedResources::ClassMethods
|
17
|
+
extend InheritedResources::UrlHelpers
|
25
18
|
|
26
19
|
helper_method :collection_url, :collection_path, :resource_url, :resource_path,
|
27
20
|
:new_resource_url, :new_resource_path, :edit_resource_url, :edit_resource_path,
|
28
21
|
:resource, :collection, :resource_class
|
29
22
|
|
30
23
|
def self.inherited(base) #:nodoc:
|
31
|
-
base
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
|
36
|
-
# Call super to register class in ApplicationController
|
37
|
-
super
|
38
|
-
|
39
|
-
# Creates and sets class accessors default values
|
40
|
-
initialize_resources_class_accessors!(base)
|
24
|
+
super(base)
|
25
|
+
base.send :initialize_resources_class_accessors!
|
26
|
+
base.send :create_resources_url_helpers!
|
41
27
|
end
|
42
|
-
|
43
|
-
protected
|
44
|
-
|
45
|
-
# GET /resources
|
46
|
-
def index(&block)
|
47
|
-
respond_to(:with => collection, &block)
|
48
|
-
end
|
49
|
-
alias :index! :index
|
50
|
-
|
51
|
-
# GET /resources/1
|
52
|
-
def show(&block)
|
53
|
-
respond_to(:with => resource, &block)
|
54
|
-
end
|
55
|
-
alias :show! :show
|
56
|
-
|
57
|
-
# GET /resources/new
|
58
|
-
def new(&block)
|
59
|
-
respond_to(:with => build_resource, &block)
|
60
|
-
end
|
61
|
-
alias :new! :new
|
62
|
-
|
63
|
-
# GET /resources/1/edit
|
64
|
-
def edit(&block)
|
65
|
-
respond_to(:with => resource, &block)
|
66
|
-
end
|
67
|
-
alias :edit! :edit
|
68
|
-
|
69
|
-
# POST /resources
|
70
|
-
def create(redirect_url=nil, &block)
|
71
|
-
object = build_resource(params[resource_instance_name])
|
72
|
-
respond_block, redirect_block = select_block_by_arity(block)
|
73
|
-
|
74
|
-
if object.save
|
75
|
-
set_flash_message!(:notice, '{{resource_name}} was successfully created.')
|
76
|
-
options = { :with => object, :status => :created, :location => (resource_url rescue nil) }
|
77
|
-
|
78
|
-
respond_to_with_dual_blocks(true, respond_block, options) do |format|
|
79
|
-
format.html { redirect_to parse_redirect_url(redirect_url, :resource_url, redirect_block) }
|
80
|
-
end
|
81
|
-
else
|
82
|
-
set_flash_message!(:error)
|
83
|
-
|
84
|
-
options = { :with => object.errors, :status => :unprocessable_entity }
|
85
|
-
|
86
|
-
respond_to_with_dual_blocks(false, respond_block, options) do |format|
|
87
|
-
format.html { render :action => 'new' }
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
91
|
-
alias :create! :create
|
92
|
-
|
93
|
-
# PUT /resources/1
|
94
|
-
def update(redirect_url=nil, &block)
|
95
|
-
object = resource
|
96
|
-
respond_block, redirect_block = select_block_by_arity(block)
|
97
|
-
|
98
|
-
if object.update_attributes(params[resource_instance_name])
|
99
|
-
set_flash_message!(:notice, '{{resource_name}} was successfully updated.')
|
100
|
-
|
101
|
-
respond_to_with_dual_blocks(true, block) do |format|
|
102
|
-
format.html { redirect_to parse_redirect_url(redirect_url, :resource_url, redirect_block) }
|
103
|
-
format.all { head :ok }
|
104
|
-
end
|
105
|
-
else
|
106
|
-
set_flash_message!(:error)
|
107
|
-
|
108
|
-
options = { :with => object.errors, :status => :unprocessable_entity }
|
109
|
-
|
110
|
-
respond_to_with_dual_blocks(false, block, options) do |format|
|
111
|
-
format.html { render :action => 'edit' }
|
112
|
-
end
|
113
|
-
end
|
114
|
-
end
|
115
|
-
alias :update! :update
|
116
|
-
|
117
|
-
# DELETE /resources/1
|
118
|
-
def destroy(redirect_url=nil, &block)
|
119
|
-
resource.destroy
|
120
|
-
respond_block, redirect_block = select_block_by_arity(block)
|
121
|
-
|
122
|
-
set_flash_message!(:notice, '{{resource_name}} was successfully destroyed.')
|
123
|
-
|
124
|
-
respond_to_with_dual_blocks(nil, respond_block) do |format|
|
125
|
-
format.html { redirect_to parse_redirect_url(redirect_url, :collection_url, redirect_block) }
|
126
|
-
format.all { head :ok }
|
127
|
-
end
|
128
|
-
end
|
129
|
-
alias :destroy! :destroy
|
130
|
-
|
131
28
|
end
|
132
29
|
end
|
133
|
-
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# Whenever base is required load the dumb responder since it's used inside actions.
|
2
|
+
require File.dirname(__FILE__) + '/dumb_responder.rb'
|
3
|
+
|
1
4
|
module InheritedResources
|
2
5
|
# Base helpers for InheritedResource work. Some methods here can be overwriten
|
3
6
|
# and you will need to do that to customize your controllers from time to time.
|
@@ -42,7 +45,7 @@ module InheritedResources
|
|
42
45
|
# methods. You probably won't need to change it. Again, if you overwrite
|
43
46
|
# don't forget to cache the result in an instance_variable.
|
44
47
|
#
|
45
|
-
def build_resource(attributes
|
48
|
+
def build_resource(attributes={})
|
46
49
|
get_resource_ivar || set_resource_ivar(end_of_association_chain.send(method_for_build, attributes))
|
47
50
|
end
|
48
51
|
|
@@ -126,7 +129,14 @@ module InheritedResources
|
|
126
129
|
# Returns the appropriated method to build the resource.
|
127
130
|
#
|
128
131
|
def method_for_build #:nodoc:
|
129
|
-
(begin_of_association_chain || parent?) ?
|
132
|
+
(begin_of_association_chain || parent?) ? method_for_association_build : :new
|
133
|
+
end
|
134
|
+
|
135
|
+
# Returns the name of the method used for build the resource in cases
|
136
|
+
# where we have a parent. This is overwritten in singleton scenarios.
|
137
|
+
#
|
138
|
+
def method_for_association_build
|
139
|
+
:build
|
130
140
|
end
|
131
141
|
|
132
142
|
# Returns the name of the method to be called, before returning the end
|
@@ -297,20 +307,6 @@ module InheritedResources
|
|
297
307
|
[]
|
298
308
|
end
|
299
309
|
|
300
|
-
# If block is not nil, call it and uses the result as redirect to url.
|
301
|
-
# Otherwise, send the default url as message.
|
302
|
-
#
|
303
|
-
def parse_redirect_url(redirect_url, default_url, block) #:nodoc:
|
304
|
-
if redirect_url
|
305
|
-
line = caller.detect{|l| l =~ Regexp.new(Regexp.escape(RAILS_ROOT)) }
|
306
|
-
ActiveSupport::Deprecation.warn("#{action_name}!(redirect_url) is deprecated. " <<
|
307
|
-
"Use #{action_name}!{ redirect_url } instead.", [line])
|
308
|
-
return redirect_url
|
309
|
-
end
|
310
|
-
|
311
|
-
block ? block.call : send(default_url)
|
312
|
-
end
|
313
|
-
|
314
310
|
# Holds InheritedResources block structure. It returns two blocks: the first
|
315
311
|
# is used in respond_to blocks and the second is the redirect_to url.
|
316
312
|
#
|
@@ -53,7 +53,7 @@ module InheritedResources
|
|
53
53
|
config[key] = value.to_sym
|
54
54
|
end
|
55
55
|
|
56
|
-
|
56
|
+
create_resources_url_helpers!
|
57
57
|
end
|
58
58
|
|
59
59
|
# Defines wich actions to keep from the inherited controller.
|
@@ -244,7 +244,7 @@ module InheritedResources
|
|
244
244
|
if block_given?
|
245
245
|
class_eval(&block)
|
246
246
|
else
|
247
|
-
|
247
|
+
create_resources_url_helpers!
|
248
248
|
end
|
249
249
|
end
|
250
250
|
alias :nested_belongs_to :belongs_to
|
@@ -292,49 +292,44 @@ module InheritedResources
|
|
292
292
|
|
293
293
|
# Initialize resources class accessors and set their default values.
|
294
294
|
#
|
295
|
-
def initialize_resources_class_accessors!
|
295
|
+
def initialize_resources_class_accessors! #:nodoc:
|
296
296
|
# Add and protect class accessors
|
297
|
-
|
298
|
-
metaklass = (class << self; self; end)
|
297
|
+
metaklass = (class << self; self; end)
|
299
298
|
|
300
|
-
|
301
|
-
|
299
|
+
RESOURCES_CLASS_ACCESSORS.each do |cattr|
|
300
|
+
cattr_accessor "#{cattr}", :instance_writer => false
|
302
301
|
|
303
|
-
|
304
|
-
|
302
|
+
# Protect instance methods
|
303
|
+
self.send :protected, cattr
|
305
304
|
|
306
|
-
|
307
|
-
|
308
|
-
end
|
305
|
+
# Protect class writer
|
306
|
+
metaklass.send :protected, "#{cattr}="
|
309
307
|
end
|
310
308
|
|
311
309
|
# Initialize resource class
|
312
|
-
|
313
|
-
|
310
|
+
self.resource_class = begin
|
311
|
+
self.controller_name.classify.constantize
|
314
312
|
rescue NameError
|
315
313
|
nil
|
316
314
|
end
|
317
315
|
|
318
316
|
# Initialize resources configuration hash
|
319
|
-
|
320
|
-
config =
|
321
|
-
config[:collection_name] =
|
322
|
-
config[:instance_name] =
|
317
|
+
self.resources_configuration = {}
|
318
|
+
config = self.resources_configuration[:self] = {}
|
319
|
+
config[:collection_name] = self.controller_name.to_sym
|
320
|
+
config[:instance_name] = self.controller_name.singularize.to_sym
|
323
321
|
|
324
322
|
config[:route_collection_name] = config[:collection_name]
|
325
323
|
config[:route_instance_name] = config[:instance_name]
|
326
324
|
|
327
325
|
# Deal with namespaced controllers
|
328
|
-
namespaces =
|
326
|
+
namespaces = self.controller_path.split('/')[0..-2]
|
329
327
|
config[:route_prefix] = namespaces.join('_') unless namespaces.empty?
|
330
328
|
|
331
329
|
# Initialize polymorphic, singleton, scopes and belongs_to parameters
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
# Create helpers
|
337
|
-
InheritedResources::UrlHelpers.create_resources_url_helpers!(base)
|
330
|
+
self.parents_symbols = []
|
331
|
+
self.scopes_configuration = {}
|
332
|
+
self.resources_configuration[:polymorphic] = { :symbols => [], :optional => false }
|
338
333
|
end
|
339
334
|
|
340
335
|
end
|
@@ -80,8 +80,8 @@ module InheritedResources
|
|
80
80
|
|
81
81
|
# Returns the appropriated method to build the resource.
|
82
82
|
#
|
83
|
-
def
|
84
|
-
"build_#{resource_instance_name}"
|
83
|
+
def method_for_association_build #:nodoc:
|
84
|
+
:"build_#{resource_instance_name}"
|
85
85
|
end
|
86
86
|
|
87
87
|
# Sets the method_for_association_chain to nil. See <tt>resource</tt>
|
@@ -39,10 +39,9 @@ module InheritedResources
|
|
39
39
|
# When we are using polymorphic associations, those helpers rely on
|
40
40
|
# polymorphic_url Rails helper.
|
41
41
|
#
|
42
|
-
def
|
42
|
+
def create_resources_url_helpers!
|
43
43
|
resource_segments, resource_ivars = [], []
|
44
|
-
resource_config =
|
45
|
-
polymorphic = false
|
44
|
+
resource_config = self.resources_configuration[:self]
|
46
45
|
|
47
46
|
# Add route_prefix if any.
|
48
47
|
resource_segments << resource_config[:route_prefix] unless resource_config[:route_prefix].blank?
|
@@ -51,150 +50,108 @@ module InheritedResources
|
|
51
50
|
# Remember that we don't have to build the segments in polymorphic cases,
|
52
51
|
# because the url will be polymorphic_url.
|
53
52
|
#
|
54
|
-
|
53
|
+
self.parents_symbols.each do |symbol|
|
55
54
|
if symbol == :polymorphic
|
56
|
-
polymorphic = true
|
57
55
|
resource_ivars << :parent
|
58
56
|
else
|
59
|
-
config =
|
57
|
+
config = self.resources_configuration[symbol]
|
60
58
|
resource_segments << config[:route_name]
|
61
|
-
resource_ivars << config[:instance_name]
|
59
|
+
resource_ivars << :"@#{config[:instance_name]}"
|
62
60
|
end
|
63
61
|
end
|
64
62
|
|
65
|
-
|
63
|
+
singleton = self.resources_configuration[:self][:singleton]
|
64
|
+
polymorphic = self.parents_symbols.include?(:polymorphic)
|
65
|
+
|
66
|
+
collection_ivars = resource_ivars.dup
|
67
|
+
collection_segments = resource_segments.dup
|
68
|
+
|
69
|
+
# This is the default route configuration, later we have to deal with
|
70
|
+
# exception from polymorphic and singleton cases.
|
66
71
|
#
|
67
|
-
|
68
|
-
|
72
|
+
collection_segments << resource_config[:route_collection_name]
|
73
|
+
resource_segments << resource_config[:route_instance_name]
|
74
|
+
resource_ivars << :"@#{resource_config[:instance_name]}"
|
75
|
+
|
76
|
+
# In singleton cases, we do not send the current element instance variable
|
77
|
+
# because the id is not in the URL. For example, we should call:
|
69
78
|
#
|
70
|
-
#
|
79
|
+
# project_manager_url(@project)
|
71
80
|
#
|
72
|
-
#
|
73
|
-
# The collection_url for singleton is the parent show url. For example,
|
74
|
-
# if we have ProjectsController with ManagerController, where the second
|
75
|
-
# is the singleton, the collection url would be: project_url(@project).
|
81
|
+
# Instead of:
|
76
82
|
#
|
77
|
-
#
|
83
|
+
# project_manager_url(@project, @manager)
|
78
84
|
#
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
resource_segments.pop
|
83
|
-
else
|
84
|
-
generate_url_and_path_helpers(base, nil, :collection, resource_segments, resource_ivars, polymorphic)
|
85
|
-
end
|
86
|
-
|
87
|
-
# Prepare and add new_resource_url
|
88
|
-
resource_segments << resource_config[:route_instance_name]
|
89
|
-
generate_url_and_path_helpers(base, :new, :resource, resource_segments, resource_ivars, polymorphic)
|
90
|
-
|
91
|
-
# We don't add the resource_ivar to edit and show url if singleton.
|
92
|
-
# Singletons are simply:
|
85
|
+
# Another exception in singleton cases is that collection url does not
|
86
|
+
# exist. In such cases, we create the parent collection url. So in the
|
87
|
+
# manager case above, the collection url will be:
|
93
88
|
#
|
94
|
-
#
|
89
|
+
# project_url(@project)
|
95
90
|
#
|
96
|
-
#
|
91
|
+
# If the singleton does not have a parent, it will default to root_url.
|
97
92
|
#
|
98
|
-
#
|
93
|
+
# Finally, polymorphic cases we have to give hints to the polymorphic url
|
94
|
+
# builder. This works by attaching new ivars as symbols or records.
|
99
95
|
#
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
generate_url_and_path_helpers(base, nil, :resource, resource_segments, resource_ivars, polymorphic)
|
104
|
-
generate_url_and_path_helpers(base, :edit, :resource, resource_segments, resource_ivars, polymorphic)
|
105
|
-
end
|
106
|
-
|
107
|
-
def self.generate_url_and_path_helpers(base, prefix, name, resource_segments, resource_ivars, polymorphic=false) #:nodoc:
|
108
|
-
ivars = resource_ivars.map{|i| i == :parent ? :parent : "@#{i}" }
|
96
|
+
if singleton
|
97
|
+
collection_segments.pop
|
98
|
+
resource_ivars.pop
|
109
99
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
unless base.resources_configuration[:self][:singleton] || ivars.empty? ||
|
114
|
-
name == :collection || prefix == :new
|
115
|
-
ivars.push "(given_args.first || #{ivars.pop})"
|
100
|
+
if polymorphic
|
101
|
+
resource_ivars << resource_config[:instance_name].inspect
|
102
|
+
new_ivars = resource_ivars
|
116
103
|
end
|
104
|
+
elsif polymorphic
|
105
|
+
collection_ivars << 'resource_class.new'
|
106
|
+
end
|
117
107
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
# Customization to allow polymorphic with singletons.
|
125
|
-
#
|
126
|
-
# Let's take the projects and companies where each one has one manager
|
127
|
-
# example. The url helpers would be:
|
128
|
-
#
|
129
|
-
# company_manager_url(@company)
|
130
|
-
# project_manager_url(@project)
|
131
|
-
#
|
132
|
-
# Notice how the manager is not sent in the helper, because it's a
|
133
|
-
# singleton. So, polymorphic urls would be:
|
134
|
-
#
|
135
|
-
# polymorphic_url(@company)
|
136
|
-
# polymorphic_url(@project)
|
137
|
-
#
|
138
|
-
# Obviously, this won't work properly. So in such polymorphic with
|
139
|
-
# singletons cases we have to do this:
|
140
|
-
#
|
141
|
-
# polymorphic_url(@company, 'manager')
|
142
|
-
# polymorphic_url(@project, 'manager')
|
143
|
-
#
|
144
|
-
# This is exactly what we are doing here.
|
145
|
-
#
|
146
|
-
# The other case to handle is collection and new helpers with
|
147
|
-
# polymorphic urls. In such cases, we usually would not send anything:
|
148
|
-
#
|
149
|
-
# project_tasks_url(@project)
|
150
|
-
# new_project_task_url(@project)
|
151
|
-
#
|
152
|
-
# But this wouldn't work with polymorphic urls by the same reason as
|
153
|
-
# singletons:
|
154
|
-
#
|
155
|
-
# polymorphic_url(@project)
|
156
|
-
# new_polymorphic_url(@project)
|
157
|
-
#
|
158
|
-
# So we have to do this:
|
159
|
-
#
|
160
|
-
# polymorphic_url(@project, Task.new)
|
161
|
-
# new_polymorphic_url(@project, Task.new)
|
162
|
-
#
|
163
|
-
if base.resources_configuration[:self][:singleton]
|
164
|
-
ivars << base.resources_configuration[:self][:instance_name].inspect unless name == :collection
|
165
|
-
elsif name == :collection || prefix == :new
|
166
|
-
ivars << 'resource_class.new'
|
167
|
-
end
|
108
|
+
generate_url_and_path_helpers nil, :collection, collection_segments, collection_ivars
|
109
|
+
generate_url_and_path_helpers :new, :resource, resource_segments, new_ivars || collection_ivars
|
110
|
+
generate_url_and_path_helpers nil, :resource, resource_segments, resource_ivars
|
111
|
+
generate_url_and_path_helpers :edit, :resource, resource_segments, resource_ivars
|
112
|
+
end
|
168
113
|
|
169
|
-
|
114
|
+
def generate_url_and_path_helpers(prefix, name, resource_segments, resource_ivars) #:nodoc:
|
115
|
+
ivars = resource_ivars.dup
|
170
116
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
117
|
+
singleton = self.resources_configuration[:self][:singleton]
|
118
|
+
polymorphic = self.parents_symbols.include?(:polymorphic)
|
119
|
+
|
120
|
+
# If it's not a singleton, ivars are not empty, not a collection or
|
121
|
+
# not a "new" named route, we can pass a resource as argument.
|
122
|
+
#
|
123
|
+
unless singleton || ivars.empty? || name == :collection || prefix == :new
|
124
|
+
ivars.push "(given_args.first || #{ivars.pop})"
|
125
|
+
end
|
180
126
|
|
181
|
-
|
127
|
+
# When polymorphic is true, the segments must be replace by :polymorphic
|
128
|
+
# and ivars should be gathered into an array, which is compacted when
|
129
|
+
# optional.
|
130
|
+
#
|
131
|
+
if polymorphic
|
132
|
+
segments = :polymorphic
|
133
|
+
ivars = "[#{ivars.join(', ')}]"
|
134
|
+
ivars << '.compact' if self.resources_configuration[:polymorphic][:optional]
|
135
|
+
else
|
136
|
+
segments = resource_segments.empty? ? 'root' : resource_segments.join('_')
|
137
|
+
ivars = ivars.join(', ')
|
138
|
+
end
|
182
139
|
|
183
|
-
|
184
|
-
|
140
|
+
prefix = prefix ? "#{prefix}_" : ''
|
141
|
+
ivars << (ivars.empty? ? 'given_options' : ', given_options')
|
185
142
|
|
186
|
-
|
187
|
-
protected
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
143
|
+
class_eval <<-URL_HELPERS, __FILE__, __LINE__
|
144
|
+
protected
|
145
|
+
def #{prefix}#{name}_path(*given_args)
|
146
|
+
given_options = given_args.extract_options!
|
147
|
+
#{prefix}#{segments}_path(#{ivars})
|
148
|
+
end
|
192
149
|
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
URL_HELPERS
|
150
|
+
def #{prefix}#{name}_url(*given_args)
|
151
|
+
given_options = given_args.extract_options!
|
152
|
+
#{prefix}#{segments}_url(#{ivars})
|
153
|
+
end
|
154
|
+
URL_HELPERS
|
198
155
|
end
|
199
156
|
|
200
157
|
end
|
data/test/aliases_test.rb
CHANGED
data/test/base_test.rb
CHANGED
data/test/class_methods_test.rb
CHANGED
@@ -81,7 +81,7 @@ class DefaultsClassMethodTest < ActiveSupport::TestCase
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def test_url_helpers_are_recreated_when_defaults_change
|
84
|
-
|
84
|
+
BooksController.expects(:create_resources_url_helpers!).returns(true).once
|
85
85
|
BooksController.send(:defaults, :instance_name => 'string', :collection_name => 'strings')
|
86
86
|
end
|
87
87
|
end
|
@@ -104,7 +104,7 @@ class BelongsToErrorsTest < ActiveSupport::TestCase
|
|
104
104
|
end
|
105
105
|
|
106
106
|
def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_block
|
107
|
-
|
107
|
+
DeansController.expects(:create_resources_url_helpers!).returns(true).once
|
108
108
|
DeansController.send(:belongs_to, :school) do
|
109
109
|
belongs_to :association
|
110
110
|
end
|
@@ -113,7 +113,7 @@ class BelongsToErrorsTest < ActiveSupport::TestCase
|
|
113
113
|
end
|
114
114
|
|
115
115
|
def test_url_helpers_are_recreated_just_once_when_belongs_to_is_called_with_multiple_blocks
|
116
|
-
|
116
|
+
DeansController.expects(:create_resources_url_helpers!).returns(true).once
|
117
117
|
DeansController.send(:belongs_to, :school) do
|
118
118
|
belongs_to :association do
|
119
119
|
belongs_to :nested
|
data/test/redirect_to_test.rb
CHANGED
@@ -1,63 +1,10 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/test_helper'
|
2
2
|
|
3
|
-
class SuperMachine;
|
4
|
-
def self.human_name; 'Machine'; end
|
5
|
-
end
|
6
|
-
|
7
|
-
# Use this to test blocks with multiple arity in the future.
|
8
|
-
class SuperMachinesController < InheritedResources::Base
|
9
|
-
def create
|
10
|
-
create!('http://test.host/')
|
11
|
-
end
|
12
|
-
|
13
|
-
def update
|
14
|
-
update!('http://test.host/')
|
15
|
-
end
|
16
|
-
|
17
|
-
def destroy
|
18
|
-
destroy!('http://test.host/')
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
class RedirectToWithArgumentTest < ActionController::TestCase
|
23
|
-
tests SuperMachinesController
|
24
|
-
|
25
|
-
def test_redirect_to_the_given_url_on_create
|
26
|
-
ActiveSupport::Deprecation.expects(:warn).with('create!(redirect_url) is deprecated. Use create!{ redirect_url } instead.', [nil])
|
27
|
-
SuperMachine.stubs(:new).returns(mock_machine(:save => true))
|
28
|
-
@controller.expects(:resource_url).times(0)
|
29
|
-
post :create
|
30
|
-
assert_redirected_to 'http://test.host/'
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_redirect_to_the_given_url_on_update
|
34
|
-
ActiveSupport::Deprecation.expects(:warn).with('update!(redirect_url) is deprecated. Use update!{ redirect_url } instead.', [nil])
|
35
|
-
SuperMachine.stubs(:find).returns(mock_machine(:update_attributes => true))
|
36
|
-
@controller.expects(:resource_url).times(0)
|
37
|
-
put :update
|
38
|
-
assert_redirected_to 'http://test.host/'
|
39
|
-
end
|
40
|
-
|
41
|
-
def test_redirect_to_the_given_url_on_destroy
|
42
|
-
ActiveSupport::Deprecation.expects(:warn).with('destroy!(redirect_url) is deprecated. Use destroy!{ redirect_url } instead.', [nil])
|
43
|
-
SuperMachine.stubs(:find).returns(mock_machine(:destroy => true))
|
44
|
-
@controller.expects(:collection_url).times(0)
|
45
|
-
delete :destroy
|
46
|
-
assert_redirected_to 'http://test.host/'
|
47
|
-
end
|
48
|
-
|
49
|
-
protected
|
50
|
-
def mock_machine(stubs={})
|
51
|
-
@mock_machine ||= mock(stubs)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
3
|
class Machine;
|
56
4
|
def self.human_name; 'Machine'; end
|
57
5
|
end
|
58
6
|
|
59
7
|
class MachinesController < InheritedResources::Base
|
60
|
-
|
61
8
|
def create
|
62
9
|
create!{ complex_url(:create, true, true) }
|
63
10
|
end
|
@@ -106,3 +53,25 @@ class RedirectToWithBlockTest < ActionController::TestCase
|
|
106
53
|
end
|
107
54
|
end
|
108
55
|
|
56
|
+
|
57
|
+
# Use this to test blocks with multiple arity in the future.
|
58
|
+
class SuperMachinesController < InheritedResources::Base
|
59
|
+
defaults :resource_class => Machine
|
60
|
+
|
61
|
+
def create
|
62
|
+
create! do |arg1, arg2, arg3|
|
63
|
+
# nothing
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
class RedirectToArityTest < ActionController::TestCase
|
69
|
+
tests SuperMachinesController
|
70
|
+
|
71
|
+
def test_redirect_to_the_given_url_on_create
|
72
|
+
Machine.stubs(:new).returns(:anything)
|
73
|
+
assert_raise ScriptError, /arity/ do
|
74
|
+
post :create
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: josevalim-inherited_resources
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- "Jos\xC3\xA9 Valim"
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-05-23 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -28,6 +28,7 @@ files:
|
|
28
28
|
- Rakefile
|
29
29
|
- init.rb
|
30
30
|
- lib/inherited_resources.rb
|
31
|
+
- lib/inherited_resources/actions.rb
|
31
32
|
- lib/inherited_resources/base.rb
|
32
33
|
- lib/inherited_resources/base_helpers.rb
|
33
34
|
- lib/inherited_resources/belongs_to_helpers.rb
|