Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 349 lines (318 sloc) 12.424 kB
0cfb8c7 @ryanb adding basic ability module
authored
1 module CanCan
dfd84a1 @ryanb improving inline documentation
authored
2
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
3 # This module is designed to be included into an Ability class. This will
4 # provide the "can" methods for defining and checking abilities.
dfd84a1 @ryanb improving inline documentation
authored
5 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
6 # class Ability
7 # include CanCan::Ability
8 #
9 # def initialize(user)
10 # if user.admin?
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
11 # can :access, :all
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
12 # else
13 # can :read, :all
14 # end
15 # end
16 # end
dfd84a1 @ryanb improving inline documentation
authored
17 #
0cfb8c7 @ryanb adding basic ability module
authored
18 module Ability
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
19 # Check if the user has permission to perform a given action on an object.
dfd84a1 @ryanb improving inline documentation
authored
20 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
21 # can? :destroy, @project
dfd84a1 @ryanb improving inline documentation
authored
22 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
23 # You can also pass the class instead of an instance (if you don't have one handy).
dfd84a1 @ryanb improving inline documentation
authored
24 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
25 # can? :create, :projects
dfd84a1 @ryanb improving inline documentation
authored
26 #
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
27 # Nested resources can be passed through a hash, this way conditions which are
28 # dependent upon the association will work when using a class.
29 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
30 # can? :create, @category => :projects
dfd84a1 @ryanb improving inline documentation
authored
31 #
32 # Not only can you use the can? method in the controller and view (see ControllerAdditions),
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
33 # but you can also call it directly on an ability instance.
dfd84a1 @ryanb improving inline documentation
authored
34 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
35 # ability.can? :destroy, @project
dfd84a1 @ryanb improving inline documentation
authored
36 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
37 # This makes testing a user's abilities very easy.
dfd84a1 @ryanb improving inline documentation
authored
38 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
39 # def test "user can only destroy projects which he owns"
40 # user = User.new
41 # ability = Ability.new(user)
42 # assert ability.can?(:destroy, Project.new(:user => user))
43 # assert ability.cannot?(:destroy, Project.new)
44 # end
dfd84a1 @ryanb improving inline documentation
authored
45 #
46 # Also see the RSpec Matchers to aid in testing.
85efbdb @ryanb adding attributes as 3rd argument to can and can? calls
authored
47 def can?(action, subject, attribute = nil)
48 match = relevant_rules_for_match(action, subject, attribute).detect do |rule|
49 rule.matches_conditions?(action, subject, attribute)
7d7d249 @funny-falcon passing throw matching rules with not matching conditions
funny-falcon authored
50 end
6084814 @ryanb refactoring can definition matching behavior
authored
51 match ? match.base_behavior : false
0cfb8c7 @ryanb adding basic ability module
authored
52 end
dfd84a1 @ryanb improving inline documentation
authored
53
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
54 # Convenience method which works the same as "can?" but returns the opposite value.
dfd84a1 @ryanb improving inline documentation
authored
55 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
56 # cannot? :destroy, @project
dfd84a1 @ryanb improving inline documentation
authored
57 #
0f49b54 @ryanb adding 'cannot?' method which performs opposite check of 'can?' - clo…
authored
58 def cannot?(*args)
59 !can?(*args)
60 end
dfd84a1 @ryanb improving inline documentation
authored
61
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
62 # Defines which abilities are allowed using two arguments. The first one is the action
63 # you're setting the permission for, the second one is the class of object you're setting it on.
dfd84a1 @ryanb improving inline documentation
authored
64 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
65 # can :update, :articles
dfd84a1 @ryanb improving inline documentation
authored
66 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
67 # You can pass an array for either of these parameters to match any one.
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
68 # Here the user has the ability to update or destroy both articles and comments.
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
69 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
70 # can [:update, :destroy], [:articles, :comments]
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
71 #
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
72 # You can pass :all to match any object and :access to match any action. Here are some examples.
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
73 #
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
74 # can :access, :all
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
75 # can :update, :all
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
76 # can :access, :projects
dfd84a1 @ryanb improving inline documentation
authored
77 #
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
78 # You can pass a hash of conditions as the third argument. Here the user can only see active projects which he owns.
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
79 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
80 # can :read, :projects, :active => true, :user_id => user.id
dfd84a1 @ryanb improving inline documentation
authored
81 #
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
82 # See ActiveRecordAdditions#accessible_by for how to use this in database queries. These conditions
83 # are also used for initial attributes when building a record in ControllerAdditions#load_resource.
dfd84a1 @ryanb improving inline documentation
authored
84 #
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
85 # If the conditions hash does not give you enough control over defining abilities, you can use a block
86 # along with any Ruby code you want.
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
87 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
88 # can :update, :projects do |project|
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
89 # project.groups.include?(user.group)
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
90 # end
dfd84a1 @ryanb improving inline documentation
authored
91 #
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
92 # If the block returns true then the user has that :update ability for that project, otherwise he
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
93 # will be denied access. The downside to using a block is that it cannot be used to generate
94 # conditions for database queries.
dfd84a1 @ryanb improving inline documentation
authored
95 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
96 # IMPORTANT: Neither a hash of conditions or a block will be used when checking permission on a symbol.
dfd84a1 @ryanb improving inline documentation
authored
97 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
98 # can :update, :projects, :priority => 3
99 # can? :update, :projects # => true
dfd84a1 @ryanb improving inline documentation
authored
100 #
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
101 # If you pass no arguments to +can+, the action, class, and object will be passed to the block and the
102 # block will always be executed. This allows you to override the full behavior if the permissions are
103 # defined in an external source such as the database.
dfd84a1 @ryanb improving inline documentation
authored
104 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
105 # can do |action, subject, object|
bf9b8ad @ryanb filling in some inline documentation for 1.4
authored
106 # # check the database and return true/false
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
107 # end
dfd84a1 @ryanb improving inline documentation
authored
108 #
85efbdb @ryanb adding attributes as 3rd argument to can and can? calls
authored
109 def can(*args, &block)
110 rules << Rule.new(true, *args, &block)
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - close…
authored
111 end
dfd84a1 @ryanb improving inline documentation
authored
112
113 # Defines an ability which cannot be done. Accepts the same arguments as "can".
114 #
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - close…
authored
115 # can :read, :all
116 # cannot :read, Comment
dfd84a1 @ryanb improving inline documentation
authored
117 #
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - close…
authored
118 # A block can be passed just like "can", however if the logic is complex it is recommended
119 # to use the "can" method.
dfd84a1 @ryanb improving inline documentation
authored
120 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
121 # cannot :read, :projects do |product|
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - close…
authored
122 # product.invisible?
123 # end
dfd84a1 @ryanb improving inline documentation
authored
124 #
85efbdb @ryanb adding attributes as 3rd argument to can and can? calls
authored
125 def cannot(*args, &block)
126 rules << Rule.new(false, *args, &block)
4b6f538 @ryanb moving can definition into ability instance instead of class, this re…
authored
127 end
dfd84a1 @ryanb improving inline documentation
authored
128
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
129 # Alias one or more actions into another one.
dfd84a1 @ryanb improving inline documentation
authored
130 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
131 # alias_action :update, :destroy, :to => :modify
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
132 # can :modify, :comments
dfd84a1 @ryanb improving inline documentation
authored
133 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
134 # Then :modify permission will apply to both :update and :destroy requests.
dfd84a1 @ryanb improving inline documentation
authored
135 #
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
136 # can? :update, :comments # => true
137 # can? :destroy, :comments # => true
dfd84a1 @ryanb improving inline documentation
authored
138 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
139 # This only works in one direction. Passing the aliased action into the "can?" call
140 # will not work because aliases are meant to generate more generic actions.
dfd84a1 @ryanb improving inline documentation
authored
141 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
142 # alias_action :update, :destroy, :to => :modify
c6f9abb @ryanb updating some documentation for CanCan 2.0
authored
143 # can :update, :comments
144 # can? :modify, :comments # => false
dfd84a1 @ryanb improving inline documentation
authored
145 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
146 # The following aliases are added by default for conveniently mapping common controller actions.
dfd84a1 @ryanb improving inline documentation
authored
147 #
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
148 # alias_action :index, :show, :to => :read
149 # alias_action :new, :to => :create
150 # alias_action :edit, :to => :update
dfd84a1 @ryanb improving inline documentation
authored
151 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
152 # This way one can use params[:action] in the controller to determine the permission.
4b6f538 @ryanb moving can definition into ability instance instead of class, this re…
authored
153 def alias_action(*args)
154 target = args.pop[:to]
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
155 aliases[:actions][target] ||= []
156 aliases[:actions][target] += args
157 end
158
159 # Alias one or more subjects into another one.
160 #
161 # alias_subject :admins, :moderators, :to => :users
162 # can :update, :users
163 #
164 # Then :modify permission will apply to both :update and :destroy requests.
165 #
166 # can? :update, :admins # => true
167 # can? :update, :moderators # => true
168 #
169 # This only works in one direction. Passing the aliased subject into the "can?" call
170 # will not work because aliases are meant to generate more generic subjects.
171 #
172 # alias_subject :admins, :moderators, :to => :users
173 # can :update, :admins
174 # can? :update, :users # => false
175 #
176 def alias_subject(*args)
177 target = args.pop[:to]
178 aliases[:subjects][target] ||= []
179 aliases[:subjects][target] += args
4b6f538 @ryanb moving can definition into ability instance instead of class, this re…
authored
180 end
dfd84a1 @ryanb improving inline documentation
authored
181
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
182 # Returns a hash of action and subject aliases.
183 def aliases
184 @aliases ||= default_aliases
c40490d @ryanb refactoring ability can? method - closes #12
authored
185 end
dfd84a1 @ryanb improving inline documentation
authored
186
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
187 # Removes previously aliased actions or subjects including the defaults.
188 def clear_aliases
189 aliases[:actions] = {}
190 aliases[:subjects] = {}
7d3b4cd @ryanb Adding clear_aliased_actions to Ability which removes previously defi…
authored
191 end
dfd84a1 @ryanb improving inline documentation
authored
192
af9e77a @ryanb adding initial active record adapter
authored
193 def model_adapter(model_class, action)
bbb02f7 @ryanb dynamically detect which model adapter to use given a class
authored
194 adapter_class = ModelAdapters::AbstractAdapter.adapter_class(model_class)
3a825ed @ryanb getting all specs passing again
authored
195 adapter_class.new(model_class, relevant_rules_for_query(action, model_class.to_s.underscore.pluralize.to_sym))
e200814 @ryanb adding joins clause to accessible_by when conditions are across assoc…
authored
196 end
25637bb @ryanb removing extra white space at end of lines
authored
197
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
198 # See ControllerAdditions#authorize! for documentation.
199 def authorize!(action, subject, *args)
200 message = nil
488cc2d @ryanb require attributes to be checked on create/update action in order to …
authored
201 if args.last.kind_of?(Hash)
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
202 message = args.pop[:message]
203 end
488cc2d @ryanb require attributes to be checked on create/update action in order to …
authored
204 attribute = args.first
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
205 if cannot?(action, subject, *args)
206 message ||= unauthorized_message(action, subject)
cf2896f @ryanb renaming AccessDenied exception to Unauthorized
authored
207 raise Unauthorized.new(message, action, subject)
242e912 @ryanb refactoring fully authorized check and catching bug
authored
208 elsif sufficient_attribute_check?(action, subject, attribute) && sufficient_condition_check?(action, subject)
209 fully_authorized!(action, subject)
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
210 end
1ac8099 @ryanb return subject passed to authorize! - closes #314
authored
211 subject
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
212 end
213
214 def unauthorized_message(action, subject)
215 keys = unauthorized_message_keys(action, subject)
158c908 @ryanb adding action and subject variables to I18n unauthorized message - cl…
authored
216 variables = {:action => action.to_s}
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
217 variables[:subject] = (subject.kind_of?(Symbol) ? subject.to_s : subject.class.to_s.underscore.humanize.downcase.pluralize)
158c908 @ryanb adding action and subject variables to I18n unauthorized message - cl…
authored
218 message = I18n.translate(nil, variables.merge(:scope => :unauthorized, :default => keys + [""]))
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
219 message.blank? ? nil : message
220 end
221
a744377 @ryanb the new and create actions will now build the resource with attribute…
authored
222 def attributes_for(action, subject)
223 attributes = {}
37c1491 @ryanb renaming CanDefinition to Rule
authored
224 relevant_rules(action, subject).map do |rule|
225 attributes.merge!(rule.attributes_from_conditions) if rule.base_behavior
a744377 @ryanb the new and create actions will now build the resource with attribute…
authored
226 end
227 attributes
228 end
229
9d91545 @ryanb load the collection instance variable on index action - closes #137
authored
230 def has_block?(action, subject)
37c1491 @ryanb renaming CanDefinition to Rule
authored
231 relevant_rules(action, subject).any?(&:only_block?)
9d91545 @ryanb load the collection instance variable on index action - closes #137
authored
232 end
b0cec52 @ryanb adding a couple things to the changelog
authored
233
12037d7 @funny-falcon should not allow to can? when raw sql without block is present
funny-falcon authored
234 def has_raw_sql?(action, subject)
37c1491 @ryanb renaming CanDefinition to Rule
authored
235 relevant_rules(action, subject).any?(&:only_raw_sql?)
12037d7 @funny-falcon should not allow to can? when raw sql without block is present
funny-falcon authored
236 end
9d91545 @ryanb load the collection instance variable on index action - closes #137
authored
237
0f37534 @ryanb adding fully_authorized? method to Ability to check if conditions are…
authored
238 def has_instance_conditions?(action, subject)
239 relevant_rules(action, subject).any?(&:instance_conditions?)
240 end
241
488cc2d @ryanb require attributes to be checked on create/update action in order to …
authored
242 def has_attributes?(action, subject)
243 relevant_rules(action, subject).any?(&:attributes?)
244 end
245
0f37534 @ryanb adding fully_authorized? method to Ability to check if conditions are…
authored
246 def fully_authorized?(action, subject)
247 @fully_authorized ||= []
488cc2d @ryanb require attributes to be checked on create/update action in order to …
authored
248 @fully_authorized.include? [action.to_sym, subject.to_sym]
0f37534 @ryanb adding fully_authorized? method to Ability to check if conditions are…
authored
249 end
250
251 def fully_authorized!(action, subject)
e5b7621 @ryanb fixing marking fully_authorized on an object instance
authored
252 subject = subject.class.to_s.underscore.pluralize.to_sym unless subject.kind_of?(Symbol) || subject.kind_of?(String)
0f37534 @ryanb adding fully_authorized? method to Ability to check if conditions are…
authored
253 @fully_authorized ||= []
488cc2d @ryanb require attributes to be checked on create/update action in order to …
authored
254 @fully_authorized << [action.to_sym, subject.to_sym]
0f37534 @ryanb adding fully_authorized? method to Ability to check if conditions are…
authored
255 end
256
7797b37 @rogercampos Adding Ability#merge
rogercampos authored
257 def merge(ability)
258 ability.send(:rules).each do |rule|
259 rules << rule.dup
260 end
261 self
262 end
263
7d3b4cd @ryanb Adding clear_aliased_actions to Ability which removes previously defi…
authored
264 private
25637bb @ryanb removing extra white space at end of lines
authored
265
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
266 def unauthorized_message_keys(action, subject)
3a825ed @ryanb getting all specs passing again
authored
267 subject = (subject.kind_of?(Symbol) ? subject.to_s : subject.class.to_s.underscore.pluralize)
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
268 [aliases_for(:subjects, subject.to_sym), :all].flatten.map do |try_subject|
269 [aliases_for(:actions, action.to_sym), :access].flatten.map do |try_action|
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
270 :"#{try_action}.#{try_subject}"
271 end
272 end.flatten
273 end
274
346ca2c @ryanb check authorization is sufficient in an after_filter when doing enabl…
authored
275 def sufficient_attribute_check?(action, subject, attribute)
276 !(%w[create update].include?(action.to_s) && attribute.nil? && has_attributes?(action, subject))
277 end
278
279 def sufficient_condition_check?(action, subject)
280 !((subject.kind_of?(Symbol) || subject.kind_of?(String)) && has_instance_conditions?(action, subject))
281 end
282
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
283 # Accepts an array of actions and returns an array of actions which match.
cad4259 @ryanb supporting deeply nested aliases - closes #98
authored
284 # This should be called before "matches?" and other checking methods since they
285 # rely on the actions to be expanded.
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
286 def expand_aliases(type, items)
287 items.map do |item|
288 aliases[type][item] ? [item, *expand_aliases(type, aliases[type][item])] : item
cad4259 @ryanb supporting deeply nested aliases - closes #98
authored
289 end.flatten
290 end
dfd84a1 @ryanb improving inline documentation
authored
291
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
292 # Given an action, it will try to find all of the actions which are aliased to it.
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
293 # This does the opposite kind of lookup as expand_aliases.
294 def aliases_for(type, action)
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
295 results = [action]
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
296 aliases[type].each do |aliased_action, actions|
297 results += aliases_for(type, aliased_action) if actions.include? action
a5f838a @ryanb use I18n for unauthorization messages - closes #103
authored
298 end
299 results
300 end
301
37c1491 @ryanb renaming CanDefinition to Rule
authored
302 def rules
303 @rules ||= []
bbbc8a6 @ryanb refactoring much of Ability class into separate CanDefinition class
authored
304 end
dfd84a1 @ryanb improving inline documentation
authored
305
37c1491 @ryanb renaming CanDefinition to Rule
authored
306 # Returns an array of Rule instances which match the action and subject
6084814 @ryanb refactoring can definition matching behavior
authored
307 # This does not take into consideration any hash conditions or block statements
85efbdb @ryanb adding attributes as 3rd argument to can and can? calls
authored
308 def relevant_rules(action, subject, attribute = nil)
6de9e46 @ryanb consider specificity when finding relevant rules so generic rules wil…
authored
309 specificity = 0
310 rules.reverse.each_with_object([]) do |rule, relevant_rules|
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
311 rule.expanded_actions = expand_aliases(:actions, rule.actions)
312 rule.expanded_subjects = expand_aliases(:subjects, rule.subjects)
6de9e46 @ryanb consider specificity when finding relevant rules so generic rules wil…
authored
313 if rule.relevant?(action, subject, attribute) && rule.specificity >= specificity
314 specificity = rule.specificity if rule.base_behavior
315 relevant_rules << rule
316 end
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
317 end
318 end
b0cec52 @ryanb adding a couple things to the changelog
authored
319
85efbdb @ryanb adding attributes as 3rd argument to can and can? calls
authored
320 def relevant_rules_for_match(action, subject, attribute)
321 relevant_rules(action, subject, attribute).each do |rule|
37c1491 @ryanb renaming CanDefinition to Rule
authored
322 if rule.only_raw_sql?
12037d7 @funny-falcon should not allow to can? when raw sql without block is present
funny-falcon authored
323 raise Error, "The can? and cannot? call cannot be used with a raw sql 'can' definition. The checking code cannot be determined for #{action.inspect} #{subject.inspect}"
324 end
325 end
326 end
dfd84a1 @ryanb improving inline documentation
authored
327
37c1491 @ryanb renaming CanDefinition to Rule
authored
328 def relevant_rules_for_query(action, subject)
85efbdb @ryanb adding attributes as 3rd argument to can and can? calls
authored
329 relevant_rules(action, subject, nil).each do |rule|
37c1491 @ryanb renaming CanDefinition to Rule
authored
330 if rule.only_block?
4fe44af @ryanb be more clear about blocks not working with accessible_by - closes #130
authored
331 raise Error, "The accessible_by call cannot be used with a block 'can' definition. The SQL cannot be determined for #{action.inspect} #{subject.inspect}"
a42e067 @ryanb extracting out Query class for generating sql conditions and associat…
authored
332 end
333 end
334 end
335
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
336 def default_aliases
4b6f538 @ryanb moving can definition into ability instance instead of class, this re…
authored
337 {
98ed392 @ryanb modifying Ability to use symbol for subject instead of class, also ad…
authored
338 :subjects => {},
339 :actions => {
340 :read => [:index, :show],
341 :create => [:new],
342 :update => [:edit],
343 :destroy => [:delete],
344 }
4b6f538 @ryanb moving can definition into ability instance instead of class, this re…
authored
345 }
346 end
0cfb8c7 @ryanb adding basic ability module
authored
347 end
348 end
Something went wrong with that request. Please try again.