README.md in consul-0.10.0 vs README.md in consul-0.10.1
- old
+ new
@@ -169,12 +169,12 @@
### Powers that only check a given object
-Sometimes it is not convenient to define powers as a collection. Sometimes you only want to store a method that
-checks whether a given object is accessible.
+Sometimes it is not convenient to define powers as a collection or scope (relation).
+Sometimes you only want to store a method that checks whether a given object is accessible.
To do so, simply define a power that ends in a question mark:
class Power
@@ -239,24 +239,21 @@
Sometimes it can be useful to define powers that require context. To do so, just take an argument in your `power` block:
class Power
...
- power :assignable_story_states do |story|
- if story.finished?
- %w[delivered archived]
- else
- %w[committed started finished]
- end
+ power :client_notes do |client|
+ client.notes.where(:state => 'published')
end
end
When querying such a power, you always need to provide the context, e.g.:
- story = ...
- Power.current.assignable_story_state?(story, 'finished')
+ client = ...
+ note = ...
+ Power.current.client_note?(client, note)
### Optimizing record checks for scope powers
You can query a scope power for a given record, e.g.
@@ -384,25 +381,93 @@
class NotesController < ApplicationController
power :crud => :notes
end
+And if your power [requires context](#powers-that-require-context-arguments) (is parametrized), you can give it using the `:context` method:
+
+ class ClientNotesController < ApplicationController
+
+ power :client_notes, :context => :load_client
+
+ private
+
+ def load_client
+ @client ||= Client.find(params[:client_id])
+ end
+
+ end
+
+
+
### Auto-mapping a power scope to a controller method
It is often convenient to map a power scope to a private controller method:
class NotesController < ApplicationController
- power :notes, :as => end_of_association_chain
+ power :notes, :as => note_scope
def show
- @note = end_of_association_chain.find(params[:id])
+ @note = note_scope.find(params[:id])
end
end
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.
+
+### Multiple power-mappings for nested resources
+
+When using [nested resources](http://guides.rubyonrails.org/routing.html#nested-resources) you probably want two power
+checks and method mappings: One for the parent resource, another for the child resource.
+
+Say you have the following routes:
+
+ resources :clients do
+ resources :notes
+ end
+
+And the following power definitions:
+
+ class Power
+ ...
+
+ power :clients do |client|
+ Client.active if signed_in?
+ end
+
+ power :client_notes do |client|
+ client.notes.where(:state => 'published')
+ end
+
+ end
+
+You can now check and map both powers in the nested `NotesController`:
+
+ class NotesController < ApplicationController
+
+ power :clients, :as => :client_scope
+ power :client_notes, :context => :load_client, :as => :note_scope
+
+ def show
+ load_note
+ end
+
+ private
+
+ def load_client
+ @client ||= client_scope.find(params[:client_id])
+ end
+
+ def load_note
+ @note ||= note_scope.find(params[:id])
+ end
+
+ end
+
+Note how we provide the `Client` parameter for the `:client_notes` power by using the `:context => :load_client`
+option in the `power` directive.
### How to never forget a power check
You can force yourself to use a `power` check in every controller. This will raise `Consul::UncheckedPower` if you ever forget it: