cancan 1.2.0 → 1.3.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|