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 +77 -12
- data/lib/consul/power.rb +9 -2
- data/lib/consul/version.rb +1 -1
- data/spec/rails-2.3/Gemfile.lock +1 -1
- data/spec/rails-3.0/Gemfile.lock +1 -1
- data/spec/rails-3.2/Gemfile.lock +1 -1
- data/spec/shared/consul/power_spec.rb +12 -0
- metadata +4 -4
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
|
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 :
|
245
|
-
|
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
|
-
|
257
|
-
|
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 =>
|
408
|
+
power :notes, :as => note_scope
|
396
409
|
|
397
410
|
def show
|
398
|
-
@note =
|
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:
|
data/lib/consul/power.rb
CHANGED
@@ -10,8 +10,15 @@ module Consul
|
|
10
10
|
private
|
11
11
|
|
12
12
|
def default_include_power?(power_name, *context)
|
13
|
-
|
14
|
-
|
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)
|
data/lib/consul/version.rb
CHANGED
data/spec/rails-2.3/Gemfile.lock
CHANGED
data/spec/rails-3.0/Gemfile.lock
CHANGED
data/spec/rails-3.2/Gemfile.lock
CHANGED
@@ -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:
|
4
|
+
hash: 53
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 10
|
9
|
-
-
|
10
|
-
version: 0.10.
|
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-
|
18
|
+
date: 2013-10-07 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|