josevalim-inherited_resources 0.7.3 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
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.7.3
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
 
@@ -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 InheritedResources::ClassMethods
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.class_eval do
32
- # Make all resources actions public
33
- public *RESOURCES_ACTIONS
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?) ? :build : :new
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
- InheritedResources::UrlHelpers.create_resources_url_helpers!(self)
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
- InheritedResources::UrlHelpers.create_resources_url_helpers!(self)
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!(base) #:nodoc:
295
+ def initialize_resources_class_accessors! #:nodoc:
296
296
  # Add and protect class accessors
297
- base.class_eval do
298
- metaklass = (class << self; self; end)
297
+ metaklass = (class << self; self; end)
299
298
 
300
- RESOURCES_CLASS_ACCESSORS.each do |cattr|
301
- cattr_accessor "#{cattr}", :instance_writer => false
299
+ RESOURCES_CLASS_ACCESSORS.each do |cattr|
300
+ cattr_accessor "#{cattr}", :instance_writer => false
302
301
 
303
- # Protect instance methods
304
- self.send :protected, cattr
302
+ # Protect instance methods
303
+ self.send :protected, cattr
305
304
 
306
- # Protect class writer
307
- metaklass.send :protected, "#{cattr}="
308
- end
305
+ # Protect class writer
306
+ metaklass.send :protected, "#{cattr}="
309
307
  end
310
308
 
311
309
  # Initialize resource class
312
- base.resource_class = begin
313
- base.controller_name.classify.constantize
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
- base.resources_configuration = {}
320
- config = base.resources_configuration[:self] = {}
321
- config[:collection_name] = base.controller_name.to_sym
322
- config[:instance_name] = base.controller_name.singularize.to_sym
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 = base.controller_path.split('/')[0..-2]
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
- base.parents_symbols = []
333
- base.scopes_configuration = {}
334
- base.resources_configuration[:polymorphic] = { :symbols => [], :optional => false }
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 method_for_build #:nodoc:
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 self.create_resources_url_helpers!(base)
42
+ def create_resources_url_helpers!
43
43
  resource_segments, resource_ivars = [], []
44
- resource_config = base.resources_configuration[:self]
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
- base.parents_symbols.map do |symbol|
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 = base.resources_configuration[symbol]
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
- # Deals with singleton.
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
- # If not a singleton, we add the current collection name and build the
68
- # collection url. It can build for example:
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
- # project_tasks_url
79
+ # project_manager_url(@project)
71
80
  #
72
- # If it's a singleton we also build a collection, just for compatibility.
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
- # This is where you are going to be redirected after destroying the manager.
83
+ # project_manager_url(@project, @manager)
78
84
  #
79
- unless base.resources_configuration[:self][:singleton]
80
- resource_segments << resource_config[:route_collection_name]
81
- generate_url_and_path_helpers(base, nil, :collection, resource_segments, resource_ivars, polymorphic)
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
- # edit_project_manager_url(@project)
89
+ # project_url(@project)
95
90
  #
96
- # Instead of:
91
+ # If the singleton does not have a parent, it will default to root_url.
97
92
  #
98
- # edit_project_manager_url(@project, @manager)
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
- resource_ivars << resource_config[:instance_name] unless base.resources_configuration[:self][:singleton]
101
-
102
- # Prepare and add resource_url and edit_resource_url
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
- # If it's not a singleton, ivars are not empty, not a collection or
111
- # not a "new" named route, we can pass a resource as argument.
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
- # When polymorphic is true, the segments must be replace by :polymorphic
119
- # and ivars should be gathered into an array.
120
- #
121
- if polymorphic
122
- segments = :polymorphic
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
- ivars = "[#{ivars.join(', ')}]"
114
+ def generate_url_and_path_helpers(prefix, name, resource_segments, resource_ivars) #:nodoc:
115
+ ivars = resource_ivars.dup
170
116
 
171
- # Add compact to deal with polymorphic optional associations.
172
- ivars << '.compact' if base.resources_configuration[:polymorphic][:optional]
173
- else
174
- # In the last case, if segments is empty (this usually happens with
175
- # root singleton resources, we set it to root)
176
- #
177
- segments = resource_segments.empty? ? 'root' : resource_segments.join('_')
178
- ivars = ivars.join(', ')
179
- end
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
- prefix = prefix ? "#{prefix}_" : ''
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
- # Add given_options to ivars
184
- ivars << (ivars.empty? ? 'given_options' : ', given_options')
140
+ prefix = prefix ? "#{prefix}_" : ''
141
+ ivars << (ivars.empty? ? 'given_options' : ', given_options')
185
142
 
186
- base.class_eval <<URL_HELPERS, __FILE__, __LINE__
187
- protected
188
- def #{prefix}#{name}_path(*given_args)
189
- given_options = given_args.extract_options!
190
- #{prefix}#{segments}_path(#{ivars})
191
- end
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
- def #{prefix}#{name}_url(*given_args)
194
- given_options = given_args.extract_options!
195
- #{prefix}#{segments}_url(#{ivars})
196
- end
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
@@ -4,7 +4,8 @@ class Student;
4
4
  def self.human_name; 'Student'; end
5
5
  end
6
6
 
7
- class StudentsController < InheritedResources::Base
7
+ class StudentsController < ApplicationController
8
+ inherit_resources
8
9
 
9
10
  def edit
10
11
  edit! do |format|
data/test/base_test.rb CHANGED
@@ -4,7 +4,10 @@ class User
4
4
  def self.human_name; 'User'; end
5
5
  end
6
6
 
7
- class UsersController < InheritedResources::Base
7
+ class AccountsController < InheritedResources::Base
8
+ end
9
+
10
+ class UsersController < AccountsController
8
11
  respond_to :html, :xml
9
12
  end
10
13
 
@@ -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
- InheritedResources::UrlHelpers.expects(:create_resources_url_helpers!).returns(true).once
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
- InheritedResources::UrlHelpers.expects(:create_resources_url_helpers!).returns(true).once
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
- InheritedResources::UrlHelpers.expects(:create_resources_url_helpers!).returns(true).once
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
@@ -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.7.3
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-04-28 00:00:00 -07:00
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