inherited_resources 1.3.1 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,8 +1,16 @@
1
+ # Version 1.4.0
2
+
3
+ * Supports Ruby 2.0.0
4
+ * Added support for the strong_parameters gem. See the README for more
5
+ * Added the ability to pass without_protection when creating/updating
6
+ * Fixed multi-level nested singletons
7
+ * Correct paths now generated for uncountable shallow resources
8
+
1
9
  # Version 1.3.1
2
10
 
3
11
  * Fix polymorphic_belongs_to to get the parent
4
- * Addes support for Rails 3.2
5
- * Addes support to responders >= 0.6.0
12
+ * Added support for Rails 3.2
13
+ * Added support to responders >= 0.6.0
6
14
 
7
15
  # Version 1.3.0
8
16
 
@@ -41,7 +49,7 @@
41
49
  To install it, please do:
42
50
 
43
51
  sudo gem install has_scope
44
-
52
+
45
53
  # Version 0.9
46
54
 
47
55
  * Allow dual blocks in destroy;
data/Gemfile CHANGED
@@ -1,6 +1,7 @@
1
- source :rubygems
1
+ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 3.1'
5
+ gem 'rails', '~> 3.2'
6
6
  gem 'mocha'
7
+ gem 'turn'
data/Gemfile.lock CHANGED
@@ -3,93 +3,97 @@ PATH
3
3
  specs:
4
4
  inherited_resources (1.3.1)
5
5
  has_scope (~> 0.5.0)
6
- responders (~> 0.6)
6
+ responders (~> 0.9)
7
7
 
8
8
  GEM
9
- remote: http://rubygems.org/
9
+ remote: https://rubygems.org/
10
10
  specs:
11
- actionmailer (3.2.2)
12
- actionpack (= 3.2.2)
13
- mail (~> 2.4.0)
14
- actionpack (3.2.2)
15
- activemodel (= 3.2.2)
16
- activesupport (= 3.2.2)
11
+ actionmailer (3.2.13)
12
+ actionpack (= 3.2.13)
13
+ mail (~> 2.5.3)
14
+ actionpack (3.2.13)
15
+ activemodel (= 3.2.13)
16
+ activesupport (= 3.2.13)
17
17
  builder (~> 3.0.0)
18
18
  erubis (~> 2.7.0)
19
- journey (~> 1.0.1)
20
- rack (~> 1.4.0)
21
- rack-cache (~> 1.1)
19
+ journey (~> 1.0.4)
20
+ rack (~> 1.4.5)
21
+ rack-cache (~> 1.2)
22
22
  rack-test (~> 0.6.1)
23
- sprockets (~> 2.1.2)
24
- activemodel (3.2.2)
25
- activesupport (= 3.2.2)
23
+ sprockets (~> 2.2.1)
24
+ activemodel (3.2.13)
25
+ activesupport (= 3.2.13)
26
26
  builder (~> 3.0.0)
27
- activerecord (3.2.2)
28
- activemodel (= 3.2.2)
29
- activesupport (= 3.2.2)
27
+ activerecord (3.2.13)
28
+ activemodel (= 3.2.13)
29
+ activesupport (= 3.2.13)
30
30
  arel (~> 3.0.2)
31
31
  tzinfo (~> 0.3.29)
32
- activeresource (3.2.2)
33
- activemodel (= 3.2.2)
34
- activesupport (= 3.2.2)
35
- activesupport (3.2.2)
36
- i18n (~> 0.6)
32
+ activeresource (3.2.13)
33
+ activemodel (= 3.2.13)
34
+ activesupport (= 3.2.13)
35
+ activesupport (3.2.13)
36
+ i18n (= 0.6.1)
37
37
  multi_json (~> 1.0)
38
+ ansi (1.4.3)
38
39
  arel (3.0.2)
39
- builder (3.0.0)
40
+ builder (3.0.4)
40
41
  erubis (2.7.0)
41
42
  has_scope (0.5.1)
42
43
  hike (1.2.1)
43
- i18n (0.6.0)
44
- journey (1.0.3)
45
- json (1.6.5)
46
- mail (2.4.3)
44
+ i18n (0.6.1)
45
+ journey (1.0.4)
46
+ json (1.7.7)
47
+ mail (2.5.3)
47
48
  i18n (>= 0.4.0)
48
49
  mime-types (~> 1.16)
49
50
  treetop (~> 1.4.8)
50
51
  metaclass (0.0.1)
51
- mime-types (1.17.2)
52
- mocha (0.10.0)
52
+ mime-types (1.21)
53
+ mocha (0.13.3)
53
54
  metaclass (~> 0.0.1)
54
- multi_json (1.1.0)
55
+ multi_json (1.7.2)
55
56
  polyglot (0.3.3)
56
- rack (1.4.1)
57
+ rack (1.4.5)
57
58
  rack-cache (1.2)
58
59
  rack (>= 0.4)
59
- rack-ssl (1.3.2)
60
+ rack-ssl (1.3.3)
60
61
  rack
61
- rack-test (0.6.1)
62
+ rack-test (0.6.2)
62
63
  rack (>= 1.0)
63
- rails (3.2.2)
64
- actionmailer (= 3.2.2)
65
- actionpack (= 3.2.2)
66
- activerecord (= 3.2.2)
67
- activeresource (= 3.2.2)
68
- activesupport (= 3.2.2)
64
+ rails (3.2.13)
65
+ actionmailer (= 3.2.13)
66
+ actionpack (= 3.2.13)
67
+ activerecord (= 3.2.13)
68
+ activeresource (= 3.2.13)
69
+ activesupport (= 3.2.13)
69
70
  bundler (~> 1.0)
70
- railties (= 3.2.2)
71
- railties (3.2.2)
72
- actionpack (= 3.2.2)
73
- activesupport (= 3.2.2)
71
+ railties (= 3.2.13)
72
+ railties (3.2.13)
73
+ actionpack (= 3.2.13)
74
+ activesupport (= 3.2.13)
74
75
  rack-ssl (~> 1.3.2)
75
76
  rake (>= 0.8.7)
76
77
  rdoc (~> 3.4)
77
- thor (~> 0.14.6)
78
- rake (0.9.2.2)
79
- rdoc (3.12)
78
+ thor (>= 0.14.6, < 2.0)
79
+ rake (10.0.4)
80
+ rdoc (3.12.2)
80
81
  json (~> 1.4)
81
- responders (0.8.0)
82
+ responders (0.9.3)
82
83
  railties (~> 3.1)
83
- sprockets (2.1.2)
84
+ sprockets (2.2.2)
84
85
  hike (~> 1.2)
86
+ multi_json (~> 1.0)
85
87
  rack (~> 1.0)
86
88
  tilt (~> 1.1, != 1.3.0)
87
- thor (0.14.6)
88
- tilt (1.3.3)
89
- treetop (1.4.10)
89
+ thor (0.17.0)
90
+ tilt (1.3.6)
91
+ treetop (1.4.12)
90
92
  polyglot
91
93
  polyglot (>= 0.3.1)
92
- tzinfo (0.3.32)
94
+ turn (0.9.6)
95
+ ansi
96
+ tzinfo (0.3.37)
93
97
 
94
98
  PLATFORMS
95
99
  ruby
@@ -97,4 +101,5 @@ PLATFORMS
97
101
  DEPENDENCIES
98
102
  inherited_resources!
99
103
  mocha
100
- rails (~> 3.1)
104
+ rails (~> 3.2)
105
+ turn
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009 José Valim http://blog.plataformatec.com.br
1
+ Copyright (c) 2009-2012 José Valim http://blog.plataformatec.com.br
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.rdoc CHANGED
@@ -1,11 +1,3 @@
1
- === Deprecation notice
2
-
3
- Since Rails 3 came out, I have no longer used Inherited Resources. I have found that the
4
- responders abstraction and custom Rails generators offer the perfect balance between
5
- hiding and showing too much logic. That said, I suggest developers to make use of the
6
- responders gem (at https://github.com/plataformatec/responders) and no longer use Inherited
7
- Resources.
8
-
9
1
  == Inherited Resources
10
2
 
11
3
  Inherited Resources speeds up development by making your controllers inherit
@@ -134,6 +126,14 @@ call inherit_resources in your controller class scope:
134
126
  inherit_resources
135
127
  end
136
128
 
129
+ One reason to use the "inherit_resources" macro would be to ensure that your controller never responds with the html mime-type. InheritedResources::Base already responds_to :html, and the respond_to macro is strictly additive. Therefore, if you want to create a controller that, for example, responds ONLY via :js, you will have write it this way:
130
+
131
+ class AccountsController < ApplicationController
132
+ respond_to :js
133
+ inherit_resources
134
+ end
135
+
136
+
137
137
  == Overwriting defaults
138
138
 
139
139
  Whenever you inherit from InheritedResources, several defaults are assumed.
@@ -218,7 +218,7 @@ provided. So you can do:
218
218
 
219
219
  class ProjectsController < InheritedResources::Base
220
220
  def destroy
221
- destroy!{ root_url }
221
+ destroy! { root_url }
222
222
  end
223
223
  end
224
224
 
@@ -298,7 +298,7 @@ in destroy action calculate in following order collection_url, parent_url, root_
298
298
 
299
299
  Example:
300
300
 
301
- class ButtonsConntroller < InheritedResources::Base
301
+ class ButtonsController < InheritedResources::Base
302
302
  belongs_to :window
303
303
  actions :all, :except => [:show, :index]
304
304
  end
@@ -360,7 +360,7 @@ If you need to configure any of these belongs to, you can nest them using blocks
360
360
 
361
361
  Warning: calling several belongs_to is the same as nesting them:
362
362
 
363
- class CommentsConroller < InheritedResources::Base
363
+ class CommentsController < InheritedResources::Base
364
364
  belongs_to :project
365
365
  belongs_to :task
366
366
  end
@@ -467,7 +467,7 @@ And they handle everything for you. :)
467
467
  resource_url(comment) # => /posts/1/comments/#{comment.to_param}
468
468
  new_resource_url # => /posts/1/comments/new
469
469
  edit_resource_url # => /posts/1/comments/#{@comment.to_param}/edit
470
- edit_resource_url(comment) #=> /posts/1/comments/#{comment.to_param}/edit
470
+ edit_resource_url(comment) # => /posts/1/comments/#{comment.to_param}/edit
471
471
  collection_url # => /posts/1/comments
472
472
  parent_url # => /posts/1
473
473
 
@@ -539,11 +539,21 @@ And then you can rewrite the last example as:
539
539
  end
540
540
  end
541
541
 
542
+ == Strong Parameters
543
+
544
+ If your controller defines a method named permitted_params, Inherited Resources will call it where it would normally call params. This allows for easy integration with the strong_parameters gem:
545
+
546
+ def permitted_params
547
+ params.permit(:widget => [:permitted_field, :other_permitted_field])
548
+ end
549
+
550
+ Note that this doesn't work if you use strong_parameters' require method instead of permit, because whereas permit returns the entire sanitized parameter hash, require returns only the sanitized params below the parameter you required.
551
+
542
552
  == Bugs and Feedback
543
553
 
544
554
  If you discover any bugs, please describe it in the issues tracker, including Rails and Inherited Resources versions.
545
555
 
546
556
  Questions are better handled on StackOverflow.
547
557
 
548
- Copyright (c) 2011 José Valim http://blog.plataformatec.com.br
558
+ Copyright (c) 2009-2012 José Valim http://blog.plataformatec.com.br
549
559
  See the attached MIT License.
data/Rakefile CHANGED
@@ -19,3 +19,6 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
19
19
  rdoc.rdoc_files.include('MIT-LICENSE')
20
20
  rdoc.rdoc_files.include('lib/**/*.rb')
21
21
  end
22
+
23
+ # Make test the default task.
24
+ task :default => :test
@@ -18,6 +18,6 @@ Gem::Specification.new do |s|
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_dependency("responders", "~> 0.6")
21
+ s.add_dependency("responders", "~> 0.9")
22
22
  s.add_dependency("has_scope", "~> 0.5.0")
23
23
  end
@@ -67,7 +67,7 @@ module InheritedResources
67
67
  end
68
68
 
69
69
  # Responsible for updating the resource in :update method. This allow you
70
- # to handle how the resource is gona be updated, let's say in a different
70
+ # to handle how the resource is going to be updated, let's say in a different
71
71
  # way then the usual :update_attributes:
72
72
  #
73
73
  # def update_resource(object, attributes)
@@ -126,8 +126,16 @@ module InheritedResources
126
126
  # current resource).
127
127
  #
128
128
  def association_chain
129
- @association_chain ||=
130
- symbols_for_association_chain.inject([begin_of_association_chain]) do |chain, symbol|
129
+ return @association_chain if @association_chain
130
+
131
+ symbol_chain = if resources_configuration[:self][:singleton]
132
+ symbols_for_association_chain.reverse
133
+ else
134
+ symbols_for_association_chain
135
+ end
136
+
137
+ @association_chain =
138
+ symbol_chain.inject([begin_of_association_chain]) do |chain, symbol|
131
139
  chain << evaluate_parent(symbol, resources_configuration[symbol], chain.last)
132
140
  end.compact.freeze
133
141
  end
@@ -164,7 +172,6 @@ module InheritedResources
164
172
 
165
173
  # This methods gets your begin_of_association_chain, join it with your
166
174
  # parents chain and returns the scoped association.
167
- #
168
175
  def end_of_association_chain #:nodoc:
169
176
  if chain = association_chain.last
170
177
  if method_for_association_chain
@@ -267,7 +274,7 @@ module InheritedResources
267
274
  # It's extend by HasScopeHelpers.
268
275
  #
269
276
  def apply_scopes_if_available(target_object) #:nodoc:
270
- respond_to?(:apply_scopes) ? apply_scopes(target_object) : target_object
277
+ respond_to?(:apply_scopes, true) ? apply_scopes(target_object) : target_object
271
278
  end
272
279
 
273
280
  # Symbols chain in base helpers return nothing. This is later overwriten
@@ -292,27 +299,46 @@ module InheritedResources
292
299
  if respond_to? :index
293
300
  url ||= collection_url rescue nil
294
301
  end
295
- if respond_to? :parent
302
+ if respond_to? :parent, true
296
303
  url ||= parent_url rescue nil
297
304
  end
298
305
  url ||= root_url rescue nil
299
306
  end
300
307
 
301
- # extract attributes from params
308
+ # memoize the extraction of attributes from params
302
309
  def resource_params
303
- rparams = [params[resource_request_name] || params[resource_instance_name] || {}]
304
- rparams << as_role if role_given?
310
+ @resource_params ||= build_resource_params
311
+ end
312
+
313
+ # extract attributes from params
314
+ def build_resource_params
315
+ parameters = respond_to?(:permitted_params) ? permitted_params : params
316
+ rparams = [parameters[resource_request_name] || parameters[resource_instance_name] || {}]
317
+ if without_protection_given?
318
+ rparams << without_protection
319
+ else
320
+ rparams << as_role if role_given?
321
+ end
322
+
305
323
  rparams
306
324
  end
307
-
325
+
308
326
  # checking if role given
309
327
  def role_given?
310
328
  self.resources_configuration[:self][:role].present?
311
329
  end
312
-
330
+
313
331
  # getting role for mass-asignment
314
332
  def as_role
315
- { :as => self.resources_configuration[:self][:role] }
333
+ { :as => self.resources_configuration[:self][:role] }
334
+ end
335
+
336
+ def without_protection_given?
337
+ self.resources_configuration[:self][:without_protection].present?
338
+ end
339
+
340
+ def without_protection
341
+ { :without_protection => self.resources_configuration[:self][:without_protection] }
316
342
  end
317
343
  end
318
344
  end
@@ -74,13 +74,21 @@ module InheritedResources
74
74
  instantiated_object = instance_variable_get("@#{parent_config[:instance_name]}")
75
75
  return instantiated_object if instantiated_object
76
76
 
77
- parent = if chain
78
- chain.send(parent_config[:collection_name])
77
+ if parent_config[:singleton]
78
+ parent = if chain
79
+ chain.send(parent_config[:instance_name])
80
+ else
81
+ nil
82
+ end
79
83
  else
80
- parent_config[:parent_class]
81
- end
84
+ parent = if chain
85
+ chain.send(parent_config[:collection_name])
86
+ else
87
+ parent_config[:parent_class]
88
+ end
82
89
 
83
- parent = parent.send(parent_config[:finder], params[parent_config[:param]])
90
+ parent = parent.send(parent_config[:finder], params[parent_config[:param]])
91
+ end
84
92
 
85
93
  instance_variable_set("@#{parent_config[:instance_name]}", parent)
86
94
  end
@@ -62,7 +62,7 @@ module InheritedResources
62
62
  create_resources_url_helpers!
63
63
  end
64
64
 
65
- # Defines wich actions to keep from the inherited controller.
65
+ # Defines wich actions will be inherited from the inherited controller.
66
66
  # Syntax is borrowed from resource_controller.
67
67
  #
68
68
  # actions :index, :show, :edit
@@ -145,13 +145,11 @@ module InheritedResources
145
145
 
146
146
  optional = options.delete(:optional)
147
147
  shallow = options.delete(:shallow)
148
- singleton = options.delete(:singleton)
149
148
  polymorphic = options.delete(:polymorphic)
150
149
  finder = options.delete(:finder)
151
150
 
152
151
  include BelongsToHelpers if self.parents_symbols.empty?
153
152
 
154
- acts_as_singleton! if singleton
155
153
  acts_as_polymorphic! if polymorphic || optional
156
154
  acts_as_shallow! if shallow
157
155
 
@@ -181,7 +179,7 @@ module InheritedResources
181
179
  nil
182
180
  end
183
181
 
184
-
182
+ config[:singleton] = options.delete(:singleton) || false
185
183
  config[:collection_name] = options.delete(:collection_name) || symbol.to_s.pluralize.to_sym
186
184
  config[:instance_name] = options.delete(:instance_name) || symbol
187
185
  config[:param] = options.delete(:param) || :"#{symbol}_id"
@@ -260,7 +258,11 @@ module InheritedResources
260
258
  # Makes sense when using rails 3.1 mass assignment conventions
261
259
  def with_role(role)
262
260
  self.resources_configuration[:self][:role] = role.try(:to_sym)
263
- end
261
+ end
262
+
263
+ def without_protection(flag)
264
+ self.resources_configuration[:self][:without_protection] = flag
265
+ end
264
266
 
265
267
  private
266
268
 
@@ -142,7 +142,7 @@ module InheritedResources
142
142
  end.compact
143
143
 
144
144
  if keys.empty?
145
- raise ScriptError, "Could not find param for polymorphic association. The request" <<
145
+ raise ScriptError, "Could not find param for polymorphic association. The request " <<
146
146
  "parameters are #{params.keys.inspect} and the polymorphic " <<
147
147
  "associations are #{polymorphic_config[:symbols].inspect}." unless polymorphic_config[:optional]
148
148
 
@@ -47,7 +47,8 @@ module InheritedResources
47
47
  resource_segments, resource_ivars = [], []
48
48
  resource_config = self.resources_configuration[:self]
49
49
 
50
- singleton = self.resources_configuration[:self][:singleton]
50
+ singleton = resource_config[:singleton]
51
+ uncountable = !singleton && resource_config[:route_collection_name] == resource_config[:route_instance_name]
51
52
  polymorphic = self.parents_symbols.include?(:polymorphic)
52
53
 
53
54
  # Add route_prefix if any.
@@ -68,8 +69,14 @@ module InheritedResources
68
69
  resource_ivars << :parent
69
70
  else
70
71
  config = self.resources_configuration[symbol]
71
- resource_segments << config[:route_name]
72
- resource_ivars << :"@#{config[:instance_name]}"
72
+ if config[:singleton] && polymorphic
73
+ resource_ivars << config[:instance_name].inspect
74
+ else
75
+ resource_segments << config[:route_name]
76
+ end
77
+ if !config[:singleton]
78
+ resource_ivars << :"@#{config[:instance_name]}"
79
+ end
73
80
  end
74
81
  end
75
82
 
@@ -123,9 +130,8 @@ module InheritedResources
123
130
  end
124
131
 
125
132
  # If route is uncountable then add "_index" suffix to collection index route name
126
- #
127
- if !singleton && resource_config[:route_collection_name] == resource_config[:route_instance_name]
128
- collection_segments << :index
133
+ if uncountable
134
+ collection_segments << :"#{collection_segments.pop}_index"
129
135
  end
130
136
 
131
137
  generate_url_and_path_helpers nil, :collection, collection_segments, collection_ivars
@@ -1,3 +1,3 @@
1
1
  module InheritedResources
2
- VERSION = '1.3.1'.freeze
2
+ VERSION = '1.4.0'.freeze
3
3
  end
data/test/base_test.rb CHANGED
@@ -178,7 +178,7 @@ class CreateActionBaseTest < ActionController::TestCase
178
178
  post :create, :user => {:these => 'params'}
179
179
  assert_equal mock_user, assigns(:user)
180
180
  end
181
-
181
+
182
182
  def test_expose_a_newly_create_user_when_saved_with_success_and_role_setted
183
183
  @controller.class.send(:with_role, :admin)
184
184
  User.expects(:new).with({'these' => 'params'}, {:as => :admin}).returns(mock_user(:save => true))
@@ -187,6 +187,14 @@ class CreateActionBaseTest < ActionController::TestCase
187
187
  @controller.class.send(:with_role, nil)
188
188
  end
189
189
 
190
+ def test_expose_a_newly_create_user_when_saved_with_success_and_without_protection_setted
191
+ @controller.class.send(:without_protection, true)
192
+ User.expects(:new).with({'these' => 'params'}, {:without_protection => true}).returns(mock_user(:save => true))
193
+ post :create, :user => {:these => 'params'}
194
+ assert_equal mock_user, assigns(:user)
195
+ @controller.class.send(:without_protection, nil)
196
+ end
197
+
190
198
  def test_redirect_to_the_created_user
191
199
  User.stubs(:new).returns(mock_user(:save => true))
192
200
  @controller.expects(:resource_url).returns('http://test.host/')
@@ -229,7 +237,7 @@ class UpdateActionBaseTest < ActionController::TestCase
229
237
  put :update, :id => '42', :user => {:these => 'params'}
230
238
  assert_equal mock_user, assigns(:user)
231
239
  end
232
-
240
+
233
241
  def test_update_the_requested_object_when_setted_role
234
242
  @controller.class.send(:with_role, :admin)
235
243
  User.expects(:find).with('42').returns(mock_user)
@@ -239,6 +247,15 @@ class UpdateActionBaseTest < ActionController::TestCase
239
247
  @controller.class.send(:with_role, nil)
240
248
  end
241
249
 
250
+ def test_update_the_requested_object_when_setted_without_protection
251
+ @controller.class.send(:without_protection, true)
252
+ User.expects(:find).with('42').returns(mock_user)
253
+ mock_user.expects(:update_attributes).with({'these' => 'params'}, {:without_protection => true}).returns(true)
254
+ put :update, :id => '42', :user => {:these => 'params'}
255
+ assert_equal mock_user, assigns(:user)
256
+ @controller.class.send(:without_protection, nil)
257
+ end
258
+
242
259
  def test_redirect_to_the_updated_user
243
260
  User.stubs(:find).returns(mock_user(:update_attributes => true))
244
261
  @controller.expects(:resource_url).returns('http://test.host/')
@@ -0,0 +1,167 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ # This test file is instead to test the how controller flow and actions
4
+ # using a belongs_to association. This is done using mocks a la rspec.
5
+ #
6
+ class Party
7
+ extend ActiveModel::Naming
8
+ end
9
+
10
+ class Venue
11
+ extend ActiveModel::Naming
12
+ end
13
+
14
+ class Address
15
+ extend ActiveModel::Naming
16
+ end
17
+
18
+ ActiveSupport::Inflector.inflections do |inflect|
19
+ inflect.singular "address", "address"
20
+ inflect.plural "address", "addresses"
21
+ end
22
+
23
+ class VenueController < InheritedResources::Base
24
+ defaults :singleton => true
25
+ belongs_to :party
26
+ end
27
+
28
+ # for the slightly pathological
29
+ # /party/37/venue/address case
30
+ class AddressController < InheritedResources::Base
31
+ defaults :singleton => true
32
+ belongs_to :venue, :singleton => true do
33
+ belongs_to :party
34
+ end
35
+ end
36
+
37
+ #and the more pathological case
38
+ class GeolocationController < InheritedResources::Base
39
+ defaults :singleton => true
40
+ belongs_to :address, :singleton => true do
41
+ belongs_to :venue, :singleton => true do
42
+ belongs_to :party
43
+ end
44
+ end
45
+ end
46
+
47
+ class NestedSingletonTest < ActionController::TestCase
48
+ tests AddressController
49
+
50
+ def setup
51
+ @controller.stubs(:resource_url).returns('/')
52
+ @controller.stubs(:collection_url).returns('/')
53
+ end
54
+
55
+ def test_does_not_break_parent_controller
56
+ #this is kind of tacky, but seems to work
57
+ old_controller = @controller
58
+ @controller = VenueController.new
59
+ Party.expects(:find).with('37').returns(mock_party)
60
+ mock_party.expects(:venue).returns(mock_venue)
61
+ get :show, :party_id => '37'
62
+ assert_equal mock_party, assigns(:party)
63
+ assert_equal mock_venue, assigns(:venue)
64
+ ensure
65
+ @controller = old_controller
66
+ end
67
+
68
+ def test_does_not_break_child_controller
69
+ #this is kind of tacky, but seems to work
70
+ old_controller = @controller
71
+ @controller = GeolocationController.new
72
+ Party.expects(:find).with('37').returns(mock_party)
73
+ mock_party.expects(:venue).returns(mock_venue)
74
+ mock_venue.expects(:address).returns(mock_address)
75
+ mock_address.expects(:geolocation).returns(mock_geolocation)
76
+ get :show, :party_id => '37'
77
+ assert_equal mock_party, assigns(:party)
78
+ assert_equal mock_venue, assigns(:venue)
79
+ assert_equal mock_address, assigns(:address)
80
+ assert_equal mock_geolocation, assigns(:geolocation)
81
+ ensure
82
+ @controller = old_controller
83
+ end
84
+
85
+
86
+ def test_expose_a_new_address_on_new
87
+ Party.expects(:find).with('37').returns(mock_party)
88
+ mock_party.expects(:venue).returns(mock_venue)
89
+ mock_venue.expects(:build_address).returns(mock_address)
90
+ get :new, :party_id => '37'
91
+ assert_equal mock_party, assigns(:party)
92
+ assert_equal mock_venue, assigns(:venue)
93
+ assert_equal mock_address, assigns(:address)
94
+ end
95
+
96
+ def test_expose_the_address_on_edit
97
+ Party.expects(:find).with('37').returns(mock_party)
98
+ mock_party.expects(:venue).returns(mock_venue)
99
+ mock_venue.expects(:address).returns(mock_address)
100
+ get :edit, :party_id => '37'
101
+ assert_equal mock_party, assigns(:party)
102
+ assert_equal mock_venue, assigns(:venue)
103
+ assert_equal mock_address, assigns(:address)
104
+ assert_response :success
105
+ end
106
+
107
+ def test_expose_the_address_on_show
108
+ Party.expects(:find).with('37').returns(mock_party)
109
+ mock_party.expects(:venue).returns(mock_venue)
110
+ mock_venue.expects(:address).returns(mock_address)
111
+ get :show, :party_id => '37'
112
+ assert_equal mock_party, assigns(:party)
113
+ assert_equal mock_venue, assigns(:venue)
114
+ assert_equal mock_address, assigns(:address)
115
+ assert_response :success
116
+ end
117
+
118
+ def test_expose_a_newly_create_address_on_create
119
+ Party.expects(:find).with('37').returns(mock_party)
120
+ mock_party.expects(:venue).returns(mock_venue)
121
+ mock_venue.expects(:build_address).with({'these' => 'params'}).returns(mock_address(:save => true))
122
+ post :create, :party_id => '37', :address => {:these => 'params'}
123
+ assert_equal mock_party, assigns(:party)
124
+ assert_equal mock_venue, assigns(:venue)
125
+ assert_equal mock_address, assigns(:address)
126
+ end
127
+
128
+ def test_update_the_requested_object_on_update
129
+ Party.expects(:find).with('37').returns(mock_party)
130
+ mock_party.expects(:venue).returns(mock_venue(:address => mock_address))
131
+ mock_address.expects(:update_attributes).with({'these' => 'params'}).returns(mock_address(:save => true))
132
+ post :update, :party_id => '37', :address => {:these => 'params'}
133
+ assert_equal mock_party, assigns(:party)
134
+ assert_equal mock_venue, assigns(:venue)
135
+ assert_equal mock_address, assigns(:address)
136
+ end
137
+
138
+ def test_the_requested_manager_is_destroyed_on_destroy
139
+ Party.expects(:find).with('37').returns(mock_party)
140
+ mock_party.expects(:venue).returns(mock_venue)
141
+ mock_venue.expects(:address).returns(mock_address)
142
+ @controller.expects(:parent_url).returns('http://test.host/')
143
+ mock_address.expects(:destroy)
144
+ delete :destroy, :party_id => '37'
145
+ assert_equal mock_party, assigns(:party)
146
+ assert_equal mock_venue, assigns(:venue)
147
+ assert_equal mock_address, assigns(:address)
148
+ end
149
+
150
+
151
+ protected
152
+ def mock_party(stubs={})
153
+ @mock_party ||= mock('party',stubs)
154
+ end
155
+
156
+ def mock_venue(stubs={})
157
+ @mock_venue ||= mock('venue',stubs)
158
+ end
159
+
160
+ def mock_address(stubs={})
161
+ @mock_address ||= mock('address',stubs)
162
+ end
163
+
164
+ def mock_geolocation(stubs={})
165
+ @mock_geolocation ||= mock('geolocation', stubs)
166
+ end
167
+ end
@@ -13,7 +13,8 @@ class Manager
13
13
  end
14
14
 
15
15
  class ManagersController < InheritedResources::Base
16
- belongs_to :store, :singleton => true
16
+ defaults :singleton => true
17
+ belongs_to :store
17
18
  end
18
19
 
19
20
  class SingletonTest < ActionController::TestCase
@@ -0,0 +1,34 @@
1
+ require File.expand_path('test_helper', File.dirname(__FILE__))
2
+
3
+ class Widget
4
+ extend ActiveModel::Naming
5
+ end
6
+
7
+ class WidgetsController < InheritedResources::Base
8
+ end
9
+
10
+ class StrongParametersTest < ActionController::TestCase
11
+ def setup
12
+ @controller = WidgetsController.new
13
+ @controller.stubs(:widget_url).returns("/")
14
+ @controller.stubs(:permitted_params).returns(:widget => {:permitted => 'param'})
15
+ end
16
+
17
+ def test_permitted_params_from_new
18
+ Widget.expects(:new).with(:permitted => 'param')
19
+ get :new, :widget => { :permitted => 'param', :prohibited => 'param' }
20
+ end
21
+
22
+ def test_permitted_params_from_create
23
+ Widget.expects(:new).with(:permitted => 'param').returns(mock(:save => true))
24
+ post :create, :widget => { :permitted => 'param', :prohibited => 'param' }
25
+ end
26
+
27
+ def test_permitted_params_from_update
28
+ mock_widget = mock
29
+ mock_widget.stubs(:class).returns(Widget)
30
+ mock_widget.expects(:update_attributes).with(:permitted => 'param')
31
+ Widget.expects(:find).with('42').returns(mock_widget)
32
+ put :update, :id => '42', :widget => {:permitted => 'param', :prohibited => 'param'}
33
+ end
34
+ end
data/test/test_helper.rb CHANGED
@@ -4,7 +4,8 @@ require 'bundler'
4
4
  Bundler.setup
5
5
 
6
6
  require 'test/unit'
7
- require 'mocha'
7
+ require 'mocha/setup'
8
+ begin; require 'turn/autorun'; rescue LoadError; end
8
9
 
9
10
  ENV["RAILS_ENV"] = "test"
10
11
  RAILS_ROOT = "anywhere"
@@ -45,7 +45,21 @@ class ChairsController < InheritedResources::Base
45
45
  end
46
46
 
47
47
  class OwnersController < InheritedResources::Base
48
- singleton_belongs_to :house
48
+ defaults :singleton => true
49
+
50
+ belongs_to :house
51
+ end
52
+
53
+ class Fireplace
54
+ extend ActiveModel::Naming
55
+ end
56
+ class Flame
57
+ extend ActiveModel::Naming
58
+ end
59
+ class FlamesController < InheritedResources::Base
60
+ belongs_to :house do
61
+ belongs_to :fireplace, :singleton => true
62
+ end
49
63
  end
50
64
 
51
65
  class Bed
@@ -62,6 +76,13 @@ class SheepController < InheritedResources::Base
62
76
  belongs_to :news, :table, :polymorphic => true
63
77
  end
64
78
 
79
+ class Fish
80
+ extend ActiveModel::Naming
81
+ end
82
+ class FishController < InheritedResources::Base
83
+ belongs_to :bed, :shallow => true
84
+ end
85
+
65
86
  class Desk
66
87
  extend ActiveModel::Naming
67
88
  end
@@ -80,6 +101,23 @@ class DishesController < InheritedResources::Base
80
101
  end
81
102
  end
82
103
 
104
+ class Dishwasher
105
+ extend ActiveModel::Naming
106
+ end
107
+ class Fork
108
+ extend ActiveModel::Naming
109
+ end
110
+ class Spot
111
+ extend ActiveModel::Naming
112
+ end
113
+ class SpotsController < InheritedResources::Base
114
+ belongs_to :house do
115
+ belongs_to :dishwasher, :singleton => true do
116
+ polymorphic_belongs_to :dish, :fork
117
+ end
118
+ end
119
+ end
120
+
83
121
  class Center
84
122
  extend ActiveModel::Naming
85
123
  end
@@ -244,6 +282,38 @@ class UrlHelpersTest < ActiveSupport::TestCase
244
282
  controller.send("resource_#{path_or_url}", :arg, :page => 1)
245
283
  end
246
284
  end
285
+
286
+ def test_url_helpers_on_singleton_belongs_to
287
+ controller = FlamesController.new
288
+ controller.instance_variable_set('@house', :house)
289
+ controller.instance_variable_set('@fireplace', :fireplace)
290
+ controller.instance_variable_set('@flame', :flame)
291
+
292
+ [:url, :path].each do |path_or_url|
293
+ controller.expects("house_fireplace_flames_#{path_or_url}").with(:house, {}).once
294
+ controller.send("collection_#{path_or_url}")
295
+
296
+ controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once
297
+ controller.send("resource_#{path_or_url}")
298
+
299
+ controller.expects("new_house_fireplace_flame_#{path_or_url}").with(:house, {}).once
300
+ controller.send("new_resource_#{path_or_url}")
301
+
302
+ controller.expects("edit_house_fireplace_flame_#{path_or_url}").with(:house, :flame, {}).once
303
+ controller.send("edit_resource_#{path_or_url}")
304
+
305
+ controller.expects("house_fireplace_#{path_or_url}").with(:house, {}).once
306
+ controller.send("parent_#{path_or_url}")
307
+
308
+ controller.expects("edit_house_fireplace_#{path_or_url}").with(:house, {}).once
309
+ controller.send("edit_parent_#{path_or_url}")
310
+
311
+ # With options
312
+ # Also tests that argument sent are not used
313
+ controller.expects("house_fireplace_flame_#{path_or_url}").with(:house, :arg, :page => 1).once
314
+ controller.send("resource_#{path_or_url}", :arg, :page => 1)
315
+ end
316
+ end
247
317
 
248
318
  def test_url_helpers_on_belongs_to
249
319
  controller = TablesController.new
@@ -396,6 +466,80 @@ class UrlHelpersTest < ActiveSupport::TestCase
396
466
  controller.send("resource_#{path_or_url}", :arg, :page => 1)
397
467
  end
398
468
  end
469
+
470
+ def test_url_helpers_on_nested_polymorphic_belongs_to
471
+ house = House.new
472
+ table = Table.new
473
+ dish = Dish.new
474
+
475
+ new_dish = Dish.new
476
+ Dish.stubs(:new).returns(new_dish)
477
+ new_dish.stubs(:persisted?).returns(false)
478
+
479
+ controller = DishesController.new
480
+ controller.instance_variable_set('@parent_type', :table)
481
+ controller.instance_variable_set('@house', house)
482
+ controller.instance_variable_set('@table', table)
483
+ controller.instance_variable_set('@dish', dish)
484
+
485
+ [:url, :path].each do |path_or_url|
486
+ mock_polymorphic(controller, "house_table_dishes_#{path_or_url}").with(house, table).once
487
+ controller.send("collection_#{path_or_url}")
488
+
489
+ mock_polymorphic(controller, "house_table_dish_#{path_or_url}").with(house, table, dish).once
490
+ controller.send("resource_#{path_or_url}")
491
+
492
+ mock_polymorphic(controller, "new_house_table_dish_#{path_or_url}").with(house, table).once
493
+ controller.send("new_resource_#{path_or_url}")
494
+
495
+ mock_polymorphic(controller, "edit_house_table_dish_#{path_or_url}").with(house, table, dish).once
496
+ controller.send("edit_resource_#{path_or_url}")
497
+
498
+ mock_polymorphic(controller, "house_table_#{path_or_url}").with(house, table).once
499
+ controller.send("parent_#{path_or_url}")
500
+
501
+ mock_polymorphic(controller, "edit_house_table_#{path_or_url}").with(house, table).once
502
+ controller.send("edit_parent_#{path_or_url}")
503
+ end
504
+ end
505
+
506
+ def test_url_helpers_on_singleton_and_polymorphic_belongs_to
507
+ house = House.new
508
+ dishwasher = Dishwasher.new
509
+ fork = Fork.new
510
+ spot = Spot.new
511
+
512
+ new_spot = Spot.new
513
+ Spot.stubs(:new).returns(new_spot)
514
+ new_spot.stubs(:persisted?).returns(false)
515
+
516
+ controller = SpotsController.new
517
+ controller.instance_variable_set('@parent_type', :fork)
518
+ controller.instance_variable_set('@house', house)
519
+ controller.instance_variable_set('@dishwasher', dishwasher)
520
+ controller.instance_variable_set('@fork', fork)
521
+ controller.instance_variable_set('@spot', spot)
522
+
523
+ [:url, :path].each do |path_or_url|
524
+ mock_polymorphic(controller, "house_dishwasher_fork_spots_#{path_or_url}").with(house, fork).once
525
+ controller.send("collection_#{path_or_url}")
526
+
527
+ mock_polymorphic(controller, "house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once
528
+ controller.send("resource_#{path_or_url}")
529
+
530
+ mock_polymorphic(controller, "new_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork).once
531
+ controller.send("new_resource_#{path_or_url}")
532
+
533
+ mock_polymorphic(controller, "edit_house_dishwasher_fork_spot_#{path_or_url}").with(house, fork, spot).once
534
+ controller.send("edit_resource_#{path_or_url}")
535
+
536
+ mock_polymorphic(controller, "house_dishwasher_fork_#{path_or_url}").with(house, fork).once
537
+ controller.send("parent_#{path_or_url}")
538
+
539
+ mock_polymorphic(controller, "edit_house_dishwasher_fork_#{path_or_url}").with(house, fork).once
540
+ controller.send("edit_parent_#{path_or_url}")
541
+ end
542
+ end
399
543
 
400
544
  def test_url_helpers_on_polymorphic_belongs_to
401
545
  house = House.new
@@ -505,6 +649,39 @@ class UrlHelpersTest < ActiveSupport::TestCase
505
649
  controller.send("parent_url", :arg)
506
650
  end
507
651
 
652
+ def test_url_helpers_on_shallow_belongs_to_using_uncountable
653
+ fish = Fish.new
654
+ bed = Bed.new
655
+
656
+ new_fish = Fish.new
657
+ new_fish.stubs(:persisted?).returns(false)
658
+ Sheep.stubs(:new).returns(new_fish)
659
+
660
+ controller = FishController.new
661
+ controller.instance_variable_set('@bed', bed)
662
+ controller.instance_variable_set('@fish', fish)
663
+
664
+ [:url, :path].each do |path_or_url|
665
+ controller.expects("bed_fish_index_#{path_or_url}").with(bed, {}).once
666
+ controller.send("collection_#{path_or_url}")
667
+
668
+ controller.expects("fish_#{path_or_url}").with(fish, {}).once
669
+ controller.send("resource_#{path_or_url}")
670
+
671
+ controller.expects("new_bed_fish_#{path_or_url}").with(bed, {}).once
672
+ controller.send("new_resource_#{path_or_url}")
673
+
674
+ controller.expects("edit_fish_#{path_or_url}").with(fish, {}).once
675
+ controller.send("edit_resource_#{path_or_url}")
676
+
677
+ controller.expects("bed_#{path_or_url}").with(bed, {}).once
678
+ controller.send("parent_#{path_or_url}")
679
+
680
+ controller.expects("edit_bed_#{path_or_url}").with(bed, {}).once
681
+ controller.send("edit_parent_#{path_or_url}")
682
+ end
683
+ end
684
+
508
685
  def test_url_helpers_on_namespaced_polymorphic_belongs_to
509
686
  house = House.new
510
687
  desk = Desk.new
@@ -0,0 +1 @@
1
+ edit html
@@ -0,0 +1 @@
1
+ new html
@@ -0,0 +1 @@
1
+ show html
@@ -0,0 +1 @@
1
+ show html
@@ -0,0 +1 @@
1
+ show html
File without changes
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inherited_resources
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,22 +9,27 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-08 00:00:00.000000000 Z
12
+ date: 2013-03-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: responders
16
- requirement: &70244803257400 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
20
20
  - !ruby/object:Gem::Version
21
- version: '0.6'
21
+ version: '0.9'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70244803257400
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '0.9'
25
30
  - !ruby/object:Gem::Dependency
26
31
  name: has_scope
27
- requirement: &70244803256640 !ruby/object:Gem::Requirement
32
+ requirement: !ruby/object:Gem::Requirement
28
33
  none: false
29
34
  requirements:
30
35
  - - ~>
@@ -32,7 +37,12 @@ dependencies:
32
37
  version: 0.5.0
33
38
  type: :runtime
34
39
  prerelease: false
35
- version_requirements: *70244803256640
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 0.5.0
36
46
  description: Inherited Resources speeds up development by making your controllers
37
47
  inherit all restful actions so you just have to focus on what is important.
38
48
  email: developers@plataformatec.com.br
@@ -80,12 +90,17 @@ files:
80
90
  - test/nested_belongs_to_test.rb
81
91
  - test/nested_belongs_to_with_shallow_test.rb
82
92
  - test/nested_model_with_shallow_test.rb
93
+ - test/nested_singleton_test.rb
83
94
  - test/optional_belongs_to_test.rb
84
95
  - test/polymorphic_test.rb
85
96
  - test/redirect_to_test.rb
86
97
  - test/singleton_test.rb
98
+ - test/strong_parameters_test.rb
87
99
  - test/test_helper.rb
88
100
  - test/url_helpers_test.rb
101
+ - test/views/address/edit.html.erb
102
+ - test/views/address/new.html.erb
103
+ - test/views/address/show.html.erb
89
104
  - test/views/cars/edit.html.erb
90
105
  - test/views/cars/index.html.erb
91
106
  - test/views/cars/new.html.erb
@@ -103,6 +118,7 @@ files:
103
118
  - test/views/employees/index.html.erb
104
119
  - test/views/employees/new.html.erb
105
120
  - test/views/employees/show.html.erb
121
+ - test/views/geolocation/show.html.erb
106
122
  - test/views/groups/edit.html.erb
107
123
  - test/views/managers/edit.html.erb
108
124
  - test/views/managers/new.html.erb
@@ -156,6 +172,8 @@ files:
156
172
  - test/views/users/new.html.erb
157
173
  - test/views/users/show.html.erb
158
174
  - test/views/users/update.js.erb
175
+ - test/views/venue/show.html.erb
176
+ - test/views/widgets/new.html.erb
159
177
  homepage: http://github.com/josevalim/inherited_resources
160
178
  licenses: []
161
179
  post_install_message:
@@ -168,21 +186,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
168
186
  - - ! '>='
169
187
  - !ruby/object:Gem::Version
170
188
  version: '0'
171
- segments:
172
- - 0
173
- hash: 2360799182694923826
174
189
  required_rubygems_version: !ruby/object:Gem::Requirement
175
190
  none: false
176
191
  requirements:
177
192
  - - ! '>='
178
193
  - !ruby/object:Gem::Version
179
194
  version: '0'
180
- segments:
181
- - 0
182
- hash: 2360799182694923826
183
195
  requirements: []
184
196
  rubyforge_project: inherited_resources
185
- rubygems_version: 1.8.11
197
+ rubygems_version: 1.8.23
186
198
  signing_key:
187
199
  specification_version: 3
188
200
  summary: Inherited Resources speeds up development by making your controllers inherit
@@ -203,12 +215,17 @@ test_files:
203
215
  - test/nested_belongs_to_test.rb
204
216
  - test/nested_belongs_to_with_shallow_test.rb
205
217
  - test/nested_model_with_shallow_test.rb
218
+ - test/nested_singleton_test.rb
206
219
  - test/optional_belongs_to_test.rb
207
220
  - test/polymorphic_test.rb
208
221
  - test/redirect_to_test.rb
209
222
  - test/singleton_test.rb
223
+ - test/strong_parameters_test.rb
210
224
  - test/test_helper.rb
211
225
  - test/url_helpers_test.rb
226
+ - test/views/address/edit.html.erb
227
+ - test/views/address/new.html.erb
228
+ - test/views/address/show.html.erb
212
229
  - test/views/cars/edit.html.erb
213
230
  - test/views/cars/index.html.erb
214
231
  - test/views/cars/new.html.erb
@@ -226,6 +243,7 @@ test_files:
226
243
  - test/views/employees/index.html.erb
227
244
  - test/views/employees/new.html.erb
228
245
  - test/views/employees/show.html.erb
246
+ - test/views/geolocation/show.html.erb
229
247
  - test/views/groups/edit.html.erb
230
248
  - test/views/managers/edit.html.erb
231
249
  - test/views/managers/new.html.erb
@@ -279,3 +297,5 @@ test_files:
279
297
  - test/views/users/new.html.erb
280
298
  - test/views/users/show.html.erb
281
299
  - test/views/users/update.js.erb
300
+ - test/views/venue/show.html.erb
301
+ - test/views/widgets/new.html.erb