cancan 1.2.0 → 1.3.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.rdoc +38 -0
- data/README.rdoc +14 -9
- data/Rakefile +12 -12
- data/lib/cancan.rb +1 -1
- data/lib/cancan/ability.rb +32 -35
- data/lib/cancan/active_record_additions.rb +3 -4
- data/lib/cancan/can_definition.rb +37 -47
- data/lib/cancan/controller_additions.rb +58 -26
- data/lib/cancan/controller_resource.rb +115 -40
- data/lib/cancan/query.rb +97 -0
- data/spec/cancan/ability_spec.rb +94 -43
- data/spec/cancan/active_record_additions_spec.rb +27 -4
- data/spec/cancan/can_definition_spec.rb +7 -7
- data/spec/cancan/controller_additions_spec.rb +12 -6
- data/spec/cancan/controller_resource_spec.rb +218 -26
- data/spec/cancan/query_spec.rb +107 -0
- data/spec/matchers.rb +13 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +25 -1
- metadata +10 -17
- data/lib/cancan/resource_authorization.rb +0 -70
- data/spec/cancan/resource_authorization_spec.rb +0 -135
data/CHANGELOG.rdoc
CHANGED
@@ -1,3 +1,41 @@
|
|
1
|
+
1.3.2 (August 7, 2010)
|
2
|
+
|
3
|
+
* Fixing slice error when passing in custom resource name - see issue #112
|
4
|
+
|
5
|
+
|
6
|
+
1.3.1 (August 6, 2010)
|
7
|
+
|
8
|
+
* Fixing protected sanitize_sql error - see issue #111
|
9
|
+
|
10
|
+
|
11
|
+
1.3.0 (August 6, 2010)
|
12
|
+
|
13
|
+
* Adding :find_by option to load_resource - see issue #19
|
14
|
+
|
15
|
+
* Adding :singleton option to load_resource - see issue #93
|
16
|
+
|
17
|
+
* Supporting multiple resources in :through option for polymorphic
|
18
|
+
associations - see issue #73
|
19
|
+
|
20
|
+
* Supporting Single Table Inheritance for "can" comparisons - see issue #55
|
21
|
+
|
22
|
+
* Adding :instance_name option to load/authorize_resource - see issue #44
|
23
|
+
|
24
|
+
* Don't pass nil to "new" to keep MongoMapper happy - see issue #63
|
25
|
+
|
26
|
+
* Parent resources are now authorized with :read action.
|
27
|
+
|
28
|
+
* Changing :resource option in load/authorize_resource back to :class with ability to pass false
|
29
|
+
|
30
|
+
* Removing :nested option in favor of :through option with separate load/authorize call
|
31
|
+
|
32
|
+
* Moving internal logic from ResourceAuthorization to ControllerResource class
|
33
|
+
|
34
|
+
* Supporting multiple "can" and "cannot" calls with accessible_by (thanks funny-falcon) - see issue #71
|
35
|
+
|
36
|
+
* Supporting deeply nested aliases - see issue #98
|
37
|
+
|
38
|
+
|
1
39
|
1.2.0 (July 16, 2010)
|
2
40
|
|
3
41
|
* Load nested parent resources on collection actions such as "index" (thanks dohzya)
|
data/README.rdoc
CHANGED
@@ -1,18 +1,22 @@
|
|
1
1
|
= CanCan
|
2
2
|
|
3
|
-
Wiki[http://wiki.github.com/ryanb/cancan] | RDocs[http://rdoc.info/projects/ryanb/cancan] | Screencast[http://railscasts.com/episodes/192-authorization-with-cancan]
|
3
|
+
Wiki[http://wiki.github.com/ryanb/cancan] | RDocs[http://rdoc.info/projects/ryanb/cancan] | Screencast[http://railscasts.com/episodes/192-authorization-with-cancan]
|
4
4
|
|
5
|
-
CanCan is an authorization solution for Ruby on Rails
|
5
|
+
CanCan is an authorization solution for Ruby on Rails for restricting what a given user is allowed to access throughout the application. It does not care how your user roles are defined, it simply focusses on keeping permission logic in a single location (the +Ability+ class) so it is not duplicated across controllers, views, and database queries.
|
6
6
|
|
7
|
-
|
7
|
+
By default, the +current_user+ method is required, so if you have not already, set up some authentication (such as Authlogic[http://github.com/binarylogic/authlogic] or Devise[http://github.com/plataformatec/devise]). See {Changing Defaults}[http://wiki.github.com/ryanb/cancan/changing-defaults] if you need different behavior.
|
8
8
|
|
9
9
|
|
10
10
|
== Installation
|
11
11
|
|
12
|
-
|
12
|
+
To install CanCan, include the gem in the environment.rb in Rails 2.3.
|
13
13
|
|
14
14
|
config.gem "cancan"
|
15
15
|
|
16
|
+
Or the Gemfile in Rails 3.
|
17
|
+
|
18
|
+
gem "cancan"
|
19
|
+
|
16
20
|
Alternatively it can be installed as a plugin.
|
17
21
|
|
18
22
|
script/plugin install git://github.com/ryanb/cancan.git
|
@@ -20,11 +24,11 @@ Alternatively it can be installed as a plugin.
|
|
20
24
|
|
21
25
|
== Getting Started
|
22
26
|
|
23
|
-
First, define a class called +Ability+ in "models/ability.rb". It should look something like this.
|
27
|
+
First, define a class called +Ability+ in "models/ability.rb" or anywhere else in the load path. It should look something like this.
|
24
28
|
|
25
29
|
class Ability
|
26
30
|
include CanCan::Ability
|
27
|
-
|
31
|
+
|
28
32
|
def initialize(user)
|
29
33
|
if user.admin?
|
30
34
|
can :manage, :all
|
@@ -55,7 +59,7 @@ Setting this for every action can be tedious, therefore the +load_and_authorize_
|
|
55
59
|
|
56
60
|
class ArticlesController < ApplicationController
|
57
61
|
load_and_authorize_resource
|
58
|
-
|
62
|
+
|
59
63
|
def show
|
60
64
|
# @article is already loaded and authorized
|
61
65
|
end
|
@@ -136,7 +140,8 @@ See {Fetching Records}[http://wiki.github.com/ryanb/cancan/fetching-records] for
|
|
136
140
|
|
137
141
|
== Additional Docs
|
138
142
|
|
139
|
-
* {Upgrading to 1.
|
143
|
+
* {Upgrading to 1.3}[http://wiki.github.com/ryanb/cancan/upgrading-to-13]
|
144
|
+
* {Nested Resources}[http://wiki.github.com/ryanb/cancan/nested-resources]
|
140
145
|
* {Testing Abilities}[http://wiki.github.com/ryanb/cancan/testing-abilities]
|
141
146
|
* {Accessing Request Data}[http://wiki.github.com/ryanb/cancan/accessing-request-data]
|
142
147
|
* {Admin Namespace}[http://wiki.github.com/ryanb/cancan/admin-namespace]
|
@@ -144,4 +149,4 @@ See {Fetching Records}[http://wiki.github.com/ryanb/cancan/fetching-records] for
|
|
144
149
|
|
145
150
|
== Special Thanks
|
146
151
|
|
147
|
-
CanCan was inspired by declarative_authorization[http://github.com/stffn/declarative_authorization/] and aegis[http://github.com/makandra/aegis].
|
152
|
+
CanCan was inspired by declarative_authorization[http://github.com/stffn/declarative_authorization/] and aegis[http://github.com/makandra/aegis]. Also many thanks to the CanCan contributors[http://github.com/ryanb/cancan/contributors]. See the CHANGELOG[http://github.com/ryanb/cancan/blob/master/CHANGELOG.rdoc] for the full list.
|
data/Rakefile
CHANGED
@@ -1,13 +1,13 @@
|
|
1
|
-
require 'rubygems'
|
2
|
-
require 'rake'
|
3
|
-
require 'spec/rake/spectask'
|
4
|
-
|
5
|
-
spec_files = Rake::FileList["spec/**/*_spec.rb"]
|
6
|
-
|
7
|
-
desc "Run specs"
|
8
|
-
Spec::Rake::SpecTask.new do |t|
|
9
|
-
t.spec_files = spec_files
|
10
|
-
t.spec_opts = ["-c"]
|
11
|
-
end
|
12
|
-
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'spec/rake/spectask'
|
4
|
+
|
5
|
+
spec_files = Rake::FileList["spec/**/*_spec.rb"]
|
6
|
+
|
7
|
+
desc "Run specs"
|
8
|
+
Spec::Rake::SpecTask.new do |t|
|
9
|
+
t.spec_files = spec_files
|
10
|
+
t.spec_opts = ["-c"]
|
11
|
+
end
|
12
|
+
|
13
13
|
task :default => :spec
|
data/lib/cancan.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'cancan/ability'
|
2
2
|
require 'cancan/can_definition'
|
3
3
|
require 'cancan/controller_resource'
|
4
|
-
require 'cancan/resource_authorization'
|
5
4
|
require 'cancan/controller_additions'
|
6
5
|
require 'cancan/active_record_additions'
|
7
6
|
require 'cancan/exceptions'
|
7
|
+
require 'cancan/query'
|
data/lib/cancan/ability.rb
CHANGED
@@ -50,8 +50,10 @@ module CanCan
|
|
50
50
|
# Also see the RSpec Matchers to aid in testing.
|
51
51
|
def can?(action, subject, *extra_args)
|
52
52
|
raise Error, "Nom nom nom. I eated it." if action == :has && subject == :cheezburger
|
53
|
-
|
54
|
-
|
53
|
+
match = relevant_can_definitions(action, subject).detect do |can_definition|
|
54
|
+
can_definition.matches_conditions?(action, subject, extra_args)
|
55
|
+
end
|
56
|
+
match ? match.base_behavior : false
|
55
57
|
end
|
56
58
|
|
57
59
|
# Convenience method which works the same as "can?" but returns the opposite value.
|
@@ -180,47 +182,42 @@ module CanCan
|
|
180
182
|
@aliased_actions = {}
|
181
183
|
end
|
182
184
|
|
183
|
-
# Returns a
|
184
|
-
#
|
185
|
-
#
|
186
|
-
|
187
|
-
|
188
|
-
#
|
189
|
-
# Normally you will not call this method directly, but instead go through ActiveRecordAdditions#accessible_by method.
|
190
|
-
#
|
191
|
-
# If the ability is not defined then false is returned so be sure to take that into consideration.
|
192
|
-
# If the ability is defined using a block then this will raise an exception since a hash of conditions cannot be
|
193
|
-
# determined from that.
|
194
|
-
def conditions(action, subject, options = {})
|
195
|
-
can_definition = matching_can_definition(action, subject)
|
196
|
-
if can_definition
|
197
|
-
raise Error, "Cannot determine ability conditions from block for #{action.inspect} #{subject.inspect}" if can_definition.block
|
198
|
-
can_definition.conditions(options) || {}
|
199
|
-
else
|
200
|
-
false
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
# Returns the associations used in conditions. This is usually used in the :joins option for a search.
|
205
|
-
# See ActiveRecordAdditions#accessible_by for use in Active Record.
|
206
|
-
def association_joins(action, subject)
|
207
|
-
can_definition = matching_can_definition(action, subject)
|
208
|
-
if can_definition
|
209
|
-
raise Error, "Cannot determine association joins from block for #{action.inspect} #{subject.inspect}" if can_definition.block
|
210
|
-
can_definition.association_joins
|
211
|
-
end
|
185
|
+
# Returns a CanCan::Query instance to help generate database queries based on the ability.
|
186
|
+
# If any relevant can definitions use a block then an exception will be raised because an
|
187
|
+
# SQL query cannot be generated from blocks of code.
|
188
|
+
def query(action, subject)
|
189
|
+
Query.new(subject, relevant_can_definitions_for_query(action, subject))
|
212
190
|
end
|
213
191
|
|
214
192
|
private
|
215
193
|
|
194
|
+
# Accepts a hash of aliased actions and returns an array of actions which match.
|
195
|
+
# This should be called before "matches?" and other checking methods since they
|
196
|
+
# rely on the actions to be expanded.
|
197
|
+
def expand_actions(actions)
|
198
|
+
actions.map do |action|
|
199
|
+
aliased_actions[action] ? [action, *expand_actions(aliased_actions[action])] : action
|
200
|
+
end.flatten
|
201
|
+
end
|
202
|
+
|
216
203
|
def can_definitions
|
217
204
|
@can_definitions ||= []
|
218
205
|
end
|
219
206
|
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
207
|
+
# Returns an array of CanDefinition instances which match the action and subject
|
208
|
+
# This does not take into consideration any hash conditions or block statements
|
209
|
+
def relevant_can_definitions(action, subject)
|
210
|
+
can_definitions.reverse.select do |can_definition|
|
211
|
+
can_definition.expanded_actions = expand_actions(can_definition.actions)
|
212
|
+
can_definition.relevant? action, subject
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def relevant_can_definitions_for_query(action, subject)
|
217
|
+
relevant_can_definitions(action, subject).each do |can_definition|
|
218
|
+
if can_definition.only_block?
|
219
|
+
raise Error, "Cannot determine SQL conditions or joins from block for #{action.inspect} #{subject.inspect}"
|
220
|
+
end
|
224
221
|
end
|
225
222
|
end
|
226
223
|
|
@@ -20,12 +20,11 @@ module CanCan
|
|
20
20
|
# Here only the articles which the user can update are returned. This
|
21
21
|
# internally uses Ability#conditions method, see that for more information.
|
22
22
|
def accessible_by(ability, action = :read)
|
23
|
-
|
24
|
-
joins = ability.association_joins(action, self)
|
23
|
+
query = ability.query(action, self)
|
25
24
|
if respond_to? :where
|
26
|
-
where(conditions).joins(joins)
|
25
|
+
where(query.conditions).joins(query.joins)
|
27
26
|
else
|
28
|
-
scoped(:conditions => conditions, :joins => joins)
|
27
|
+
scoped(:conditions => query.conditions, :joins => query.joins)
|
29
28
|
end
|
30
29
|
end
|
31
30
|
end
|
@@ -3,9 +3,9 @@ module CanCan
|
|
3
3
|
# it holds the information about a "can" call made on Ability and provides
|
4
4
|
# helpful methods to determine permission checking and conditions hash generation.
|
5
5
|
class CanDefinition # :nodoc:
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
attr_reader :base_behavior, :actions
|
7
|
+
attr_writer :expanded_actions
|
8
|
+
|
9
9
|
# The first argument when initializing is the base_behavior which is a true/false
|
10
10
|
# value. True for "can" and false for "cannot". The next two arguments are the action
|
11
11
|
# and subject respectively (such as :read, @project). The third argument is a hash
|
@@ -18,51 +18,47 @@ module CanCan
|
|
18
18
|
@block = block
|
19
19
|
end
|
20
20
|
|
21
|
-
#
|
22
|
-
|
23
|
-
# rely on the actions to be expanded.
|
24
|
-
def expand_actions(aliased_actions)
|
25
|
-
@expanded_actions = @actions.map do |action|
|
26
|
-
aliased_actions[action] ? [action, *aliased_actions[action]] : action
|
27
|
-
end.flatten
|
28
|
-
end
|
29
|
-
|
30
|
-
def matches?(action, subject)
|
21
|
+
# Matches both the subject and action, not necessarily the conditions
|
22
|
+
def relevant?(action, subject)
|
31
23
|
matches_action?(action) && matches_subject?(subject)
|
32
24
|
end
|
33
25
|
|
34
|
-
|
35
|
-
|
36
|
-
@
|
26
|
+
# Matches the block or conditions hash
|
27
|
+
def matches_conditions?(action, subject, extra_args)
|
28
|
+
if @block
|
29
|
+
call_block(action, subject, extra_args)
|
30
|
+
elsif @conditions.kind_of?(Hash) && subject.class != Class
|
31
|
+
matches_conditions_hash?(subject)
|
32
|
+
else
|
33
|
+
true
|
34
|
+
end
|
37
35
|
end
|
38
36
|
|
39
|
-
# Returns a hash of conditions
|
40
|
-
|
41
|
-
|
42
|
-
if options[:tableize] && @conditions.kind_of?(Hash)
|
37
|
+
# Returns a hash of conditions, pluralizing the table names
|
38
|
+
def tableized_conditions
|
39
|
+
if @conditions
|
43
40
|
@conditions.inject({}) do |tableized_conditions, (name, value)|
|
44
|
-
name =
|
41
|
+
name = name.to_s.tableize.to_sym if value.kind_of? Hash
|
45
42
|
tableized_conditions[name] = value
|
46
43
|
tableized_conditions
|
47
44
|
end
|
48
|
-
else
|
49
|
-
@conditions
|
50
45
|
end
|
51
46
|
end
|
52
47
|
|
53
|
-
def
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
48
|
+
def only_block?
|
49
|
+
conditions_empty? && !@block.nil?
|
50
|
+
end
|
51
|
+
|
52
|
+
def conditions_empty?
|
53
|
+
@conditions == {} || @conditions.nil?
|
54
|
+
end
|
55
|
+
|
56
|
+
def associations_hash(conditions = @conditions)
|
57
|
+
hash = {}
|
58
|
+
conditions.map do |name, value|
|
59
|
+
hash[name] = associations_hash(value) if value.kind_of? Hash
|
64
60
|
end
|
65
|
-
|
61
|
+
hash
|
66
62
|
end
|
67
63
|
|
68
64
|
private
|
@@ -72,27 +68,21 @@ module CanCan
|
|
72
68
|
end
|
73
69
|
|
74
70
|
def matches_subject?(subject)
|
75
|
-
@subjects.include?(:all) || @subjects.include?(subject) ||
|
71
|
+
@subjects.include?(:all) || @subjects.include?(subject) || matches_subject_class?(subject)
|
76
72
|
end
|
77
73
|
|
78
|
-
def
|
79
|
-
|
80
|
-
call_block(action, subject, extra_args)
|
81
|
-
elsif @conditions && subject.class != Class
|
82
|
-
matches_conditions? subject
|
83
|
-
else
|
84
|
-
true
|
85
|
-
end
|
74
|
+
def matches_subject_class?(subject)
|
75
|
+
@subjects.any? { |sub| sub.kind_of?(Class) && (subject.kind_of?(sub) || subject.kind_of?(Class) && subject.ancestors.include?(sub)) }
|
86
76
|
end
|
87
77
|
|
88
|
-
def
|
78
|
+
def matches_conditions_hash?(subject, conditions = @conditions)
|
89
79
|
conditions.all? do |name, value|
|
90
80
|
attribute = subject.send(name)
|
91
81
|
if value.kind_of?(Hash)
|
92
82
|
if attribute.kind_of? Array
|
93
|
-
attribute.any? { |element|
|
83
|
+
attribute.any? { |element| matches_conditions_hash? element, value }
|
94
84
|
else
|
95
|
-
|
85
|
+
matches_conditions_hash? attribute, value
|
96
86
|
end
|
97
87
|
elsif value.kind_of?(Array) || value.kind_of?(Range)
|
98
88
|
value.include? attribute
|
@@ -11,11 +11,11 @@ module CanCan
|
|
11
11
|
# load_and_authorize_resource
|
12
12
|
# end
|
13
13
|
#
|
14
|
-
def load_and_authorize_resource(
|
15
|
-
|
14
|
+
def load_and_authorize_resource(*args)
|
15
|
+
ControllerResource.add_before_filter(self, :load_and_authorize_resource, *args)
|
16
16
|
end
|
17
17
|
|
18
|
-
# Sets up a before filter which loads the
|
18
|
+
# Sets up a before filter which loads the model resource into an instance variable.
|
19
19
|
# For example, given an ArticlesController it will load the current article into the @article
|
20
20
|
# instance variable. It does this by either calling Article.find(params[:id]) or
|
21
21
|
# Article.new(params[:article]) depending upon the action. It does nothing for the "index"
|
@@ -41,6 +41,20 @@ module CanCan
|
|
41
41
|
# end
|
42
42
|
# end
|
43
43
|
#
|
44
|
+
# If a name is provided which does not match the controller it assumes it is a parent resource. Child
|
45
|
+
# resources can then be loaded through it.
|
46
|
+
#
|
47
|
+
# class BooksController < ApplicationController
|
48
|
+
# load_resource :author
|
49
|
+
# load_resource :book, :through => :author
|
50
|
+
# end
|
51
|
+
#
|
52
|
+
# Here the author resource will be loaded before each action using params[:author_id]. The book resource
|
53
|
+
# will then be loaded through the @author instance variable.
|
54
|
+
#
|
55
|
+
# That first argument is optional and will default to the singular name of the controller.
|
56
|
+
# A hash of options (see below) can also be passed to this method to further customize it.
|
57
|
+
#
|
44
58
|
# See load_and_authorize_resource to automatically authorize the resource too.
|
45
59
|
#
|
46
60
|
# Options:
|
@@ -50,27 +64,30 @@ module CanCan
|
|
50
64
|
# [:+except+]
|
51
65
|
# Does not apply before filter to given actions.
|
52
66
|
#
|
53
|
-
# [:+
|
54
|
-
#
|
67
|
+
# [:+through+]
|
68
|
+
# Load this resource through another one. This should match the name of the parent instance variable.
|
55
69
|
#
|
56
|
-
#
|
70
|
+
# [:+singleton+]
|
71
|
+
# Pass +true+ if this is a singleton resource through a +has_one+ association.
|
57
72
|
#
|
58
|
-
#
|
73
|
+
# [:+parent+]
|
74
|
+
# True or false depending on if the resource is considered a parent resource. This defaults to +true+ if a resource
|
75
|
+
# name is given which does not match the controller.
|
59
76
|
#
|
60
|
-
#
|
77
|
+
# [:+class+]
|
78
|
+
# The class to use for the model (string or constant).
|
61
79
|
#
|
62
|
-
# [:+
|
63
|
-
# The name of the
|
80
|
+
# [:+instance_name+]
|
81
|
+
# The name of the instance variable to load the resource into.
|
64
82
|
#
|
65
|
-
#
|
83
|
+
# [:+find_by+]
|
84
|
+
# Find using a different attribute other than id. For example.
|
66
85
|
#
|
67
|
-
# [
|
68
|
-
# The class to use for the model (string or constant).
|
86
|
+
# load_resource :find_by => :permalink # will use find_by_permlink!(params[:id])
|
69
87
|
#
|
70
88
|
# [:+collection+]
|
71
89
|
# Specify which actions are resource collection actions in addition to :+index+. This
|
72
|
-
# is usually not necessary because it will try to guess depending on if
|
73
|
-
# is present in +params+.
|
90
|
+
# is usually not necessary because it will try to guess depending on if the id param is present.
|
74
91
|
#
|
75
92
|
# load_resource :collection => [:sort, :list]
|
76
93
|
#
|
@@ -81,11 +98,11 @@ module CanCan
|
|
81
98
|
#
|
82
99
|
# load_resource :new => :build
|
83
100
|
#
|
84
|
-
def load_resource(
|
85
|
-
|
101
|
+
def load_resource(*args)
|
102
|
+
ControllerResource.add_before_filter(self, :load_resource, *args)
|
86
103
|
end
|
87
104
|
|
88
|
-
# Sets up a before filter which authorizes the
|
105
|
+
# Sets up a before filter which authorizes the resource using the instance variable.
|
89
106
|
# For example, if you have an ArticlesController it will check the @article instance variable
|
90
107
|
# and ensure the user can perform the current action on it. Under the hood it is doing
|
91
108
|
# something like the following.
|
@@ -98,6 +115,19 @@ module CanCan
|
|
98
115
|
# authorize_resource
|
99
116
|
# end
|
100
117
|
#
|
118
|
+
# If you pass in the name of a resource which does not match the controller it will assume
|
119
|
+
# it is a parent resource.
|
120
|
+
#
|
121
|
+
# class BooksController < ApplicationController
|
122
|
+
# authorize_resource :author
|
123
|
+
# authorize_resource :book
|
124
|
+
# end
|
125
|
+
#
|
126
|
+
# Here it will authorize :+show+, @+author+ on every action before authorizing the book.
|
127
|
+
#
|
128
|
+
# That first argument is optional and will default to the singular name of the controller.
|
129
|
+
# A hash of options (see below) can also be passed to this method to further customize it.
|
130
|
+
#
|
101
131
|
# See load_and_authorize_resource to automatically load the resource too.
|
102
132
|
#
|
103
133
|
# Options:
|
@@ -107,17 +137,19 @@ module CanCan
|
|
107
137
|
# [:+except+]
|
108
138
|
# Does not apply before filter to given actions.
|
109
139
|
#
|
110
|
-
# [:+
|
111
|
-
#
|
140
|
+
# [:+parent+]
|
141
|
+
# True or false depending on if the resource is considered a parent resource. This defaults to +true+ if a resource
|
142
|
+
# name is given which does not match the controller.
|
112
143
|
#
|
113
|
-
#
|
144
|
+
# [:+class+]
|
145
|
+
# The class to use for the model (string or constant). This passed in when the instance variable is not set.
|
146
|
+
# Pass +false+ if there is no associated class for this resource and it will use a symbol of the resource name.
|
114
147
|
#
|
115
|
-
# [:+
|
116
|
-
# The
|
117
|
-
# to represent a resource which does not have a class.
|
148
|
+
# [:+instance_name+]
|
149
|
+
# The name of the instance variable for this resource.
|
118
150
|
#
|
119
|
-
def authorize_resource(
|
120
|
-
|
151
|
+
def authorize_resource(*args)
|
152
|
+
ControllerResource.add_before_filter(self, :authorize_resource, *args)
|
121
153
|
end
|
122
154
|
end
|
123
155
|
|