consul 0.10.0 → 0.10.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of consul might be problematic. Click here for more details.

data/README.md CHANGED
@@ -171,8 +171,8 @@ When a non-admin queries the `:users` power, she will get the following behavior
171
171
 
172
172
  ### Powers that only check a given object
173
173
 
174
- Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
175
- checks whether a given object is accessible.
174
+ Sometimes it is not convenient to define powers as a collection or scope (relation).
175
+ Sometimes you only want to store a method that checks whether a given object is accessible.
176
176
 
177
177
  To do so, simply define a power that ends in a question mark:
178
178
 
@@ -241,20 +241,17 @@ Sometimes it can be useful to define powers that require context. To do so, just
241
241
  class Power
242
242
  ...
243
243
 
244
- power :assignable_story_states do |story|
245
- if story.finished?
246
- %w[delivered archived]
247
- else
248
- %w[committed started finished]
249
- end
244
+ power :client_notes do |client|
245
+ client.notes.where(:state => 'published')
250
246
  end
251
247
 
252
248
  end
253
249
 
254
250
  When querying such a power, you always need to provide the context, e.g.:
255
251
 
256
- story = ...
257
- Power.current.assignable_story_state?(story, 'finished')
252
+ client = ...
253
+ note = ...
254
+ Power.current.client_note?(client, note)
258
255
 
259
256
 
260
257
  ### Optimizing record checks for scope powers
@@ -386,16 +383,32 @@ Because this pattern is so common, there is a shortcut `:crud` to do the same:
386
383
  end
387
384
 
388
385
 
386
+ And if your power [requires context](#powers-that-require-context-arguments) (is parametrized), you can give it using the `:context` method:
387
+
388
+ class ClientNotesController < ApplicationController
389
+
390
+ power :client_notes, :context => :load_client
391
+
392
+ private
393
+
394
+ def load_client
395
+ @client ||= Client.find(params[:client_id])
396
+ end
397
+
398
+ end
399
+
400
+
401
+
389
402
  ### Auto-mapping a power scope to a controller method
390
403
 
391
404
  It is often convenient to map a power scope to a private controller method:
392
405
 
393
406
  class NotesController < ApplicationController
394
407
 
395
- power :notes, :as => end_of_association_chain
408
+ power :notes, :as => note_scope
396
409
 
397
410
  def show
398
- @note = end_of_association_chain.find(params[:id])
411
+ @note = note_scope.find(params[:id])
399
412
  end
400
413
 
401
414
  end
@@ -403,6 +416,58 @@ It is often convenient to map a power scope to a private controller method:
403
416
  This is especially useful when you are using a RESTful controller library like [resource_controller](https://github.com/jamesgolick/resource_controller). The mapped method is aware of the `:map` option.
404
417
 
405
418
 
419
+ ### Multiple power-mappings for nested resources
420
+
421
+ When using [nested resources](http://guides.rubyonrails.org/routing.html#nested-resources) you probably want two power
422
+ checks and method mappings: One for the parent resource, another for the child resource.
423
+
424
+ Say you have the following routes:
425
+
426
+ resources :clients do
427
+ resources :notes
428
+ end
429
+
430
+ And the following power definitions:
431
+
432
+ class Power
433
+ ...
434
+
435
+ power :clients do |client|
436
+ Client.active if signed_in?
437
+ end
438
+
439
+ power :client_notes do |client|
440
+ client.notes.where(:state => 'published')
441
+ end
442
+
443
+ end
444
+
445
+ You can now check and map both powers in the nested `NotesController`:
446
+
447
+ class NotesController < ApplicationController
448
+
449
+ power :clients, :as => :client_scope
450
+ power :client_notes, :context => :load_client, :as => :note_scope
451
+
452
+ def show
453
+ load_note
454
+ end
455
+
456
+ private
457
+
458
+ def load_client
459
+ @client ||= client_scope.find(params[:client_id])
460
+ end
461
+
462
+ def load_note
463
+ @note ||= note_scope.find(params[:id])
464
+ end
465
+
466
+ end
467
+
468
+ Note how we provide the `Client` parameter for the `:client_notes` power by using the `:context => :load_client`
469
+ option in the `power` directive.
470
+
406
471
  ### How to never forget a power check
407
472
 
408
473
  You can force yourself to use a `power` check in every controller. This will raise `Consul::UncheckedPower` if you ever forget it:
@@ -10,8 +10,15 @@ module Consul
10
10
  private
11
11
 
12
12
  def default_include_power?(power_name, *context)
13
- # Everything that is not nil is considered as included
14
- !!send(power_name, *context)
13
+ result = send(power_name, *context)
14
+ # Everything that is not nil is considered as included.
15
+ # We are short-circuiting for #scoped first since sometimes
16
+ # has_many associations (which behave scopish) trigger their query
17
+ # when you try to negate them, compare them or even retrieve their
18
+ # class. Unfortunately we can only reproduce this in live Rails
19
+ # apps, not in Consul tests. Might be some standard gem that is not
20
+ # loaded in Consul tests.
21
+ result.respond_to?(:scoped) || !!result
15
22
  end
16
23
 
17
24
  def default_include_object?(power_name, *args)
@@ -1,3 +1,3 @@
1
1
  module Consul
2
- VERSION = '0.10.0'
2
+ VERSION = '0.10.1'
3
3
  end
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- consul (0.9.1)
4
+ consul (0.10.1)
5
5
  edge_rider
6
6
  memoizer
7
7
  rails
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- consul (0.9.1)
4
+ consul (0.10.1)
5
5
  edge_rider
6
6
  memoizer
7
7
  rails
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../..
3
3
  specs:
4
- consul (0.9.1)
4
+ consul (0.10.1)
5
5
  edge_rider
6
6
  memoizer
7
7
  rails
@@ -94,6 +94,18 @@ describe Consul::Power do
94
94
  @user.power.clients?.should be_true
95
95
  end
96
96
 
97
+ it 'should not trigger a query if the power returns a scope' do
98
+ Client.count.should > 0 # show that we have records in the database
99
+ Client.should_not_receive(:new) # show that no query was triggered by showing that no record was instantiated
100
+ @user.power.clients?
101
+ end
102
+
103
+ it 'should not trigger a query if the power returns a has many association' do
104
+ Note.count.should > 0 # show that we have records in the database
105
+ Note.should_not_receive(:new) # show that no query was triggered by showing that no record was instantiated
106
+ @user.power.client_notes?(@client1.reload)
107
+ end
108
+
97
109
  end
98
110
 
99
111
  context 'with a given record' do
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: consul
3
3
  version: !ruby/object:Gem::Version
4
- hash: 55
4
+ hash: 53
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 10
9
- - 0
10
- version: 0.10.0
9
+ - 1
10
+ version: 0.10.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Henning Koch
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2013-08-21 00:00:00 +02:00
18
+ date: 2013-10-07 00:00:00 +02:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency