josevalim-inherited_resources 0.7.1 → 0.7.2

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Version 0.7
2
2
 
3
+ * Allow procs as default value in has scope to be able to use values from session, for example.
4
+ * Allow blocks with arity 0 or -1 to be given as the redirect url:
5
+
6
+ def destroy
7
+ destroy!{ project_url(@project) }
8
+ end
9
+
10
+ * Allow interpolation_options to be set in the application controller.
3
11
  * Added has_scope to controller (an interface for named_scopes).
4
12
  * Added polymorphic_belongs_to, optional_belongs_to and singleton_belongs_to
5
13
  as quick methods.
data/README CHANGED
@@ -1,6 +1,6 @@
1
1
  Inherited Resources
2
2
  License: MIT
3
- Version: 0.7.1
3
+ Version: 0.7.2
4
4
 
5
5
  You can also read this README in pretty html at the GitHub project Wiki page:
6
6
 
@@ -18,7 +18,7 @@ code by following fat models and skinny controllers convention.
18
18
 
19
19
  Inherited Resources is tested and compatible with Rails 2.2.x and Rails 2.3.x.
20
20
 
21
- keywords: resources, controller, singleton, belongs_to, polymorphic and I18n
21
+ keywords: resources, controller, singleton, belongs_to, polymorphic, named_scope and I18n
22
22
 
23
23
  Installation
24
24
  ------------
@@ -135,7 +135,7 @@ and scopes (more about this below).
135
135
 
136
136
  InheritedResources also introduces another method called begin_of_association_chain.
137
137
  It's mostly used when you want to create resources based on the @current_user and
138
- you have urls like "account/projects". In such cases, so you have to do
138
+ you have urls like "account/projects". In such cases, you have to do
139
139
  @current_user.projects.find or @current_user.projects.build in your actions.
140
140
 
141
141
  You can deal with it just doing:
@@ -175,13 +175,13 @@ That's why all methods have aliases. So this is equivalent:
175
175
  end
176
176
  end
177
177
 
178
- Even more, since most of the times when you change a :create, :update or :destroy
178
+ Even more, since most of the times when you change a create, update or destroy
179
179
  action is because you want to to change to where it redirects, a shortcut is
180
180
  provided. So you can do:
181
181
 
182
182
  class ProjectsController < InheritedResources::Base
183
183
  def destroy
184
- destroy!(root_url)
184
+ destroy!{ root_url }
185
185
  end
186
186
  end
187
187
 
@@ -225,7 +225,7 @@ Looks to verbose, right? We can actually do:
225
225
  end
226
226
  end
227
227
 
228
- Much better! So explaning everything: when you give a block which expects one
228
+ Much better! So explaining everything: when you give a block which expects one
229
229
  argument it will be executed in both scenarios: success and failure. But If you
230
230
  give a block that expects two arguments, the first will be executed only in
231
231
  success scenarios and the second in failure scenarios. You keep everything
@@ -280,8 +280,15 @@ Then you will finally have:
280
280
 
281
281
  "Hooray! The project "Plataforma" was updated!"
282
282
 
283
- If your controller is namespaced, for example Admin::ProjectsController, the
284
- messages will be checked in the following order:
283
+ By default, resource name is capitalized. If you want to make it lower case, you
284
+ can add to your application controller:
285
+
286
+ def interpolation_options
287
+ { :resource_name => resource_class.human_name.downcase }
288
+ end
289
+
290
+ Finally, if your controller is namespaced, for example Admin::ProjectsController,
291
+ the messages will be checked in the following order:
285
292
 
286
293
  flash.admin.projects.create.notice
287
294
  flash.admin.actions.create.notice
@@ -302,7 +309,7 @@ it also is named_scope fluent. Let's suppose our Project model with the scopes:
302
309
 
303
310
  Your controller:
304
311
 
305
- class GraduationsController < InheritedResources::Base
312
+ class ProjectsController < InheritedResources::Base
306
313
  has_scope :featured, :boolean => true, :only => :index
307
314
  has_scope :by_methodology
308
315
  has_scope :limit, :default => 10
@@ -324,6 +331,11 @@ In the last case, it would return:
324
331
 
325
332
  { :featured => "true", :by_methodology => "agile", :limit => "20" }
326
333
 
334
+ Finally, let's suppose you store on the session how many projects the user sees
335
+ per page. In such cases, you can give a proc as default value:
336
+
337
+ has_scope :limit, :default => proc{|c| c.session[:limit] || 10 }
338
+
327
339
  Belongs to
328
340
  ----------
329
341
 
@@ -67,23 +67,23 @@ module InheritedResources
67
67
  alias :edit! :edit
68
68
 
69
69
  # POST /resources
70
- def create(redirect_to=nil, &block)
70
+ def create(redirect_url=nil, &block)
71
71
  object = build_resource(params[resource_instance_name])
72
+ respond_block, redirect_block = select_block_by_arity(block)
72
73
 
73
74
  if object.save
74
75
  set_flash_message!(:notice, '{{resource_name}} was successfully created.')
75
-
76
76
  options = { :with => object, :status => :created, :location => (resource_url rescue nil) }
77
77
 
78
- respond_to_with_dual_blocks(true, block, options) do |format|
79
- format.html { redirect_to(redirect_to || resource_url) }
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
80
  end
81
81
  else
82
82
  set_flash_message!(:error)
83
83
 
84
84
  options = { :with => object.errors, :status => :unprocessable_entity }
85
85
 
86
- respond_to_with_dual_blocks(false, block, options) do |format|
86
+ respond_to_with_dual_blocks(false, respond_block, options) do |format|
87
87
  format.html { render :action => 'new' }
88
88
  end
89
89
  end
@@ -91,14 +91,15 @@ module InheritedResources
91
91
  alias :create! :create
92
92
 
93
93
  # PUT /resources/1
94
- def update(redirect_to=nil, &block)
94
+ def update(redirect_url=nil, &block)
95
95
  object = resource
96
+ respond_block, redirect_block = select_block_by_arity(block)
96
97
 
97
98
  if object.update_attributes(params[resource_instance_name])
98
99
  set_flash_message!(:notice, '{{resource_name}} was successfully updated.')
99
100
 
100
101
  respond_to_with_dual_blocks(true, block) do |format|
101
- format.html { redirect_to(redirect_to || resource_url) }
102
+ format.html { redirect_to parse_redirect_url(redirect_url, :resource_url, redirect_block) }
102
103
  format.all { head :ok }
103
104
  end
104
105
  else
@@ -114,13 +115,14 @@ module InheritedResources
114
115
  alias :update! :update
115
116
 
116
117
  # DELETE /resources/1
117
- def destroy(redirect_to=nil, &block)
118
+ def destroy(redirect_url=nil, &block)
118
119
  resource.destroy
120
+ respond_block, redirect_block = select_block_by_arity(block)
119
121
 
120
122
  set_flash_message!(:notice, '{{resource_name}} was successfully destroyed.')
121
123
 
122
- respond_to_with_dual_blocks(nil, block) do |format|
123
- format.html { redirect_to(redirect_to || collection_url) }
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) }
124
126
  format.all { head :ok }
125
127
  end
126
128
  end
@@ -82,12 +82,9 @@ module InheritedResources
82
82
  # Overwrite this method to provide other interpolation options when
83
83
  # the flash message is going to be set.
84
84
  #
85
- # You cannot overwrite :resource_name and :default options using this
86
- # method. Check <tt>set_flash_message!</tt> for more information.
87
- #
88
- def interpolation_options
89
- { }
90
- end
85
+ # def interpolation_options
86
+ # { }
87
+ # end
91
88
 
92
89
  private
93
90
 
@@ -216,13 +213,29 @@ module InheritedResources
216
213
  # flash.cars.create.status
217
214
  # flash.actions.create.status
218
215
  #
219
- def set_flash_message!(status, default_message = '')
216
+ def set_flash_message!(status, default_message=nil)
220
217
  return flash[status] = default_message unless defined?(::I18n)
221
218
 
219
+ resource_name = if resource_class
220
+ if resource_class.respond_to?(:human_name)
221
+ resource_class.human_name
222
+ else
223
+ resource_class.name.humanize
224
+ end
225
+ else
226
+ "Resource"
227
+ end
228
+
229
+ given_options = if self.respond_to?(:interpolation_options)
230
+ interpolation_options
231
+ else
232
+ {}
233
+ end
234
+
222
235
  options = {
223
236
  :default => default_message || '',
224
- :resource_name => resource_class ? resource_class.human_name : 'Resource',
225
- }.merge(interpolation_options)
237
+ :resource_name => resource_name
238
+ }.merge(given_options)
226
239
 
227
240
  defaults = []
228
241
  slices = controller_path.split('/')
@@ -284,5 +297,36 @@ module InheritedResources
284
297
  []
285
298
  end
286
299
 
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
+ ActiveSupport::Deprecation.warn "#{action_name}!(redirect_url) is deprecated. " <<
306
+ "Use #{action_name}!{ redirect_url } instead."
307
+ return redirect_url
308
+ end
309
+
310
+ block ? block.call : send(default_url)
311
+ end
312
+
313
+ # Holds InheritedResources block structure. It returns two blocks: the first
314
+ # is used in respond_to blocks and the second is the redirect_to url.
315
+ #
316
+ def select_block_by_arity(block) #:nodoc
317
+ if block
318
+ case block.arity
319
+ when 2, 1
320
+ [block, nil]
321
+ when 0, -1
322
+ [nil, block]
323
+ else
324
+ raise ScriptError, "InheritedResources does not know how to handle blocks with arity #{block.arity}"
325
+ end
326
+ else
327
+ [nil, nil]
328
+ end
329
+ end
330
+
287
331
  end
288
332
  end
@@ -23,6 +23,7 @@ module InheritedResources
23
23
  value, call_scope = params[key], true
24
24
  elsif options.key?(:default)
25
25
  value, call_scope = options[:default], true
26
+ value = value.call(self) if value.is_a?(Proc)
26
27
  end
27
28
 
28
29
  if call_scope
@@ -7,8 +7,9 @@ end
7
7
  class TreesController < InheritedResources::Base
8
8
  has_scope :color
9
9
  has_scope :only_tall, :boolean => true, :only => :index
10
- has_scope :shadown_range, :default => 10, :except => [ :index, :show, :destroy ]
10
+ has_scope :shadown_range, :default => 10, :except => [ :index, :show, :destroy, :new ]
11
11
  has_scope :root_type, :key => :root
12
+ has_scope :calculate_height, :default => proc {|c| c.session[:height] || 20 }, :only => :new
12
13
  end
13
14
 
14
15
  class HasScopeTest < ActionController::TestCase
@@ -92,6 +93,15 @@ class HasScopeTest < ActionController::TestCase
92
93
  assert_equal({ :root => 'outside' }, assigns(:current_scopes))
93
94
  end
94
95
 
96
+ def test_scope_with_default_value_as_proc
97
+ session[:height] = 100
98
+ Tree.expects(:calculate_height).with(100).returns(Tree).in_sequence
99
+ Tree.expects(:new).returns(mock_tree).in_sequence
100
+ get :new
101
+ assert_equal(mock_tree, assigns(:tree))
102
+ assert_equal({ :calculate_height => 100 }, assigns(:current_scopes))
103
+ end
104
+
95
105
  protected
96
106
 
97
107
  def mock_tree(stubs={})
@@ -1,11 +1,11 @@
1
1
  require File.dirname(__FILE__) + '/test_helper'
2
2
 
3
- class Machine;
3
+ class SuperMachine;
4
4
  def self.human_name; 'Machine'; end
5
5
  end
6
6
 
7
- class MachinesController < InheritedResources::Base
8
-
7
+ # Use this to test blocks with multiple arity in the future.
8
+ class SuperMachinesController < InheritedResources::Base
9
9
  def create
10
10
  create!('http://test.host/')
11
11
  end
@@ -17,31 +17,87 @@ class MachinesController < InheritedResources::Base
17
17
  def destroy
18
18
  destroy!('http://test.host/')
19
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.')
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.')
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.')
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
+ class Machine;
56
+ def self.human_name; 'Machine'; end
57
+ end
58
+
59
+ class MachinesController < InheritedResources::Base
60
+
61
+ def create
62
+ create!{ complex_url(:create, true, true) }
63
+ end
64
+
65
+ def update
66
+ update!{ complex_url(:update, false, false) }
67
+ end
68
+
69
+ def destroy
70
+ destroy!{ complex_url(:destroy, true, false) }
71
+ end
20
72
 
73
+ protected
74
+ def complex_url(name, arg2, arg3)
75
+ 'http://test.host/' + name.to_s
76
+ end
21
77
  end
22
78
 
23
- class RedirectToTest < ActionController::TestCase
79
+ class RedirectToWithBlockTest < ActionController::TestCase
24
80
  tests MachinesController
25
81
 
26
82
  def test_redirect_to_the_given_url_on_create
27
83
  Machine.stubs(:new).returns(mock_machine(:save => true))
28
84
  @controller.expects(:resource_url).times(0)
29
85
  post :create
30
- assert_redirected_to 'http://test.host/'
86
+ assert_redirected_to 'http://test.host/create'
31
87
  end
32
88
 
33
89
  def test_redirect_to_the_given_url_on_update
34
90
  Machine.stubs(:find).returns(mock_machine(:update_attributes => true))
35
91
  @controller.expects(:resource_url).times(0)
36
92
  put :update
37
- assert_redirected_to 'http://test.host/'
93
+ assert_redirected_to 'http://test.host/update'
38
94
  end
39
95
 
40
96
  def test_redirect_to_the_given_url_on_destroy
41
97
  Machine.stubs(:find).returns(mock_machine(:destroy => true))
42
98
  @controller.expects(:collection_url).times(0)
43
- put :destroy
44
- assert_redirected_to 'http://test.host/'
99
+ delete :destroy
100
+ assert_redirected_to 'http://test.host/destroy'
45
101
  end
46
102
 
47
103
  protected
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.1
4
+ version: 0.7.2
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-26 00:00:00 -07:00
12
+ date: 2009-04-28 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15