cancan 1.6.0 → 1.6.10

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 CHANGED
@@ -1,3 +1,124 @@
1
+ 1.6.10 (May 7, 2013)
2
+
3
+ * fix matches_conditons_hash for string values on 1.8 (thanks rrosen)
4
+
5
+ * work around SQL injection vulnerability in older Rails versions (thanks steerio) - issue #800
6
+
7
+ * add support for nested join conditions (thanks yuszuv) - issue #806
8
+
9
+ * fix load_resource "find_by" in mongoid resources (thanks albertobajo) - issue #705
10
+
11
+ * fix namespace split behavior (thanks xinuc) - issue #668
12
+
13
+ 1.6.9 (February 4, 2013)
14
+
15
+ * fix inserting AND (NULL) to end of SQL queries (thanks jonsgreen) - issue #687
16
+
17
+ * fix merge_joins for nested association hashes (thanks DavidMikeSimon) - issues #655, #560
18
+
19
+ * raise error on recursive alias_action (thanks fl00r) - issue #660
20
+
21
+ * fix namespace controllers not loading params (thanks andhapp) - issues #670, #664
22
+
23
+
24
+ 1.6.8 (June 25, 2012)
25
+
26
+ * improved support for namespaced controllers and models
27
+
28
+ * pass :if and :unless options for load and authorize resource (thanks mauriciozaffari)
29
+
30
+ * Travis CI badge (thanks plentz)
31
+
32
+ * adding Ability#merge for combining multiple abilities (thanks rogercampos)
33
+
34
+ * support for multiple MetaWhere rules (thanks andhapp)
35
+
36
+ * various fixes for DataMapper, Mongoid, and Inherited Resource integration
37
+
38
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.7...1.6.8]
39
+
40
+
41
+ 1.6.7 (October 4, 2011)
42
+
43
+ * fixing nested resource problem caused by namespace addition - issue #482
44
+
45
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.6...1.6.7]
46
+
47
+
48
+ 1.6.6 (September 28, 2011)
49
+
50
+ * correct "return cant jump across threads" error when using check_authorization (thanks codeprimate) - issues #463, #469
51
+
52
+ * fixing tests in development by specifying with_model version (thanks kirkconnell) - issue #476
53
+
54
+ * added travis.yml file for TravisCI support (thanks bai) - issue #427
55
+
56
+ * better support for namespaced models (thanks whilefalse) - issues #424
57
+
58
+ * adding :id_param option to load_and_authorize_resource (thanks skhisma) - issue #425
59
+
60
+ * make default unauthorized message translatable text (thanks nhocki) - issue #409
61
+
62
+ * improving DataMapper behavior (thanks psanford, maxsum-corin) - issue #410, #373
63
+
64
+ * allow :find_by option to be full find method name - issue #335
65
+
66
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.5...1.6.6]
67
+
68
+
69
+ 1.6.5 (May 18, 2011)
70
+
71
+ * pass action and subject through AccessDenied exception when :through isn't found - issue #366
72
+
73
+ * many Mongoid adapter improvements (thanks rahearn, cardagin) - issues #363, #352, #343
74
+
75
+ * allow :through option to work with private controller methods - issue #360
76
+
77
+ * ensure Mongoid::Document is defined before loading Mongoid adapter - issue #359
78
+
79
+ * many DataMapper adapter improvements (thanks emmanuel) - issue #355
80
+
81
+ * handle checking nil attributes through associations (thanks thatothermitch) - issue #330
82
+
83
+ * improve scope merging - issue #328
84
+
85
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.4...1.6.5]
86
+
87
+
88
+ 1.6.4 (March 29, 2011)
89
+
90
+ * Fixed mongoid 'or' error - see issue #322
91
+
92
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.3...1.6.4]
93
+
94
+
95
+ 1.6.3 (March 25, 2011)
96
+
97
+ * Make sure ActiveRecord::Relation is defined before checking conditions against it so Rails 2 is supported again - see issue #312
98
+
99
+ * Return subject passed to authorize! - see issue #314
100
+
101
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.2...1.6.3]
102
+
103
+
104
+ 1.6.2 (March 18, 2011)
105
+
106
+ * Fixed instance loading when :singleton option is used - see issue #310
107
+
108
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.1...1.6.2]
109
+
110
+
111
+ 1.6.1 (March 15, 2011)
112
+
113
+ * Use Item.new instead of build_item for singleton resource so it doesn't effect database - see issue #304
114
+
115
+ * Made accessible_by action default to :index and parent action default to :show instead of :read - see issue #302
116
+
117
+ * Reverted Inherited Resources "collection" override since it doesn't seem to be working - see issue #305
118
+
119
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.6.0...1.6.1]
120
+
121
+
1
122
  1.6.0 (March 11, 2011)
2
123
 
3
124
  * Added MetaWhere support - see issue #194 and #261
@@ -18,6 +139,8 @@
18
139
 
19
140
  * Raise an exception when trying to make a Ability condition with both a hash of conditions and a block - see issue #269
20
141
 
142
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.5.1...1.6.0]
143
+
21
144
 
22
145
  1.5.1 (January 20, 2011)
23
146
 
@@ -25,6 +148,8 @@
25
148
 
26
149
  * Improving Mongoid support for multiple can and cannot definitions (thanks stellard) - see issue #239
27
150
 
151
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.5.0...1.5.1]
152
+
28
153
 
29
154
  1.5.0 (January 11, 2011)
30
155
 
@@ -46,6 +171,8 @@
46
171
 
47
172
  * Internal: added .rvmrc to auto-switch to 1.8.7 with gemset - see issue #231
48
173
 
174
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.4.1...1.5.0]
175
+
49
176
 
50
177
  1.4.1 (November 12, 2010)
51
178
 
@@ -59,6 +186,8 @@
59
186
 
60
187
  * Fix odd behavior when "cache_classes = false" (thanks mphalliday) - see issue #174
61
188
 
189
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.4.0...1.4.1]
190
+
62
191
 
63
192
  1.4.0 (October 5, 2010)
64
193
 
@@ -98,11 +227,15 @@
98
227
 
99
228
  * No longer calling block in +can+ definition when checking on class - see issue #116
100
229
 
230
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.3.4...1.4.0]
231
+
101
232
 
102
233
  1.3.4 (August 31, 2010)
103
234
 
104
235
  * Don't stop at +cannot+ with hash conditions when checking class (thanks tamoya) - see issue #131
105
236
 
237
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.3.3...1.3.4]
238
+
106
239
 
107
240
  1.3.3 (August 20, 2010)
108
241
 
@@ -110,16 +243,22 @@
110
243
 
111
244
  * Pluralize nested associations for conditions in accessible_by (thanks mlooney) - see issue #123
112
245
 
246
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.3.2...1.3.3]
247
+
113
248
 
114
249
  1.3.2 (August 7, 2010)
115
250
 
116
251
  * Fixing slice error when passing in custom resource name - see issue #112
117
252
 
253
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.3.1...1.3.2]
254
+
118
255
 
119
256
  1.3.1 (August 6, 2010)
120
257
 
121
258
  * Fixing protected sanitize_sql error - see issue #111
122
259
 
260
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.3.0...1.3.1]
261
+
123
262
 
124
263
  1.3.0 (August 6, 2010)
125
264
 
@@ -147,6 +286,8 @@
147
286
 
148
287
  * Supporting deeply nested aliases - see issue #98
149
288
 
289
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.2.0...1.3.0]
290
+
150
291
 
151
292
  1.2.0 (July 16, 2010)
152
293
 
@@ -162,11 +303,15 @@
162
303
 
163
304
  * Adding joins clause to accessible_by when conditions are across associations
164
305
 
306
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.1.1...1.2.0]
307
+
165
308
 
166
309
  1.1.1 (April 17, 2010)
167
310
 
168
311
  * Fixing behavior in Rails 3 by properly initializing ResourceAuthorization
169
312
 
313
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.1...1.1.1]
314
+
170
315
 
171
316
  1.1.0 (April 17, 2010)
172
317
 
@@ -190,6 +335,8 @@
190
335
 
191
336
  * Support additional arguments to can? which get passed to the block - see issue #48
192
337
 
338
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.0.2...1.1]
339
+
193
340
 
194
341
  1.0.2 (Dec 30, 2009)
195
342
 
@@ -199,6 +346,8 @@
199
346
 
200
347
  * Adding custom message argument to unauthorized! method (thanks tjwallace) - see issue #18
201
348
 
349
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.0.1...1.0.2]
350
+
202
351
 
203
352
  1.0.1 (Dec 14, 2009)
204
353
 
@@ -206,6 +355,8 @@
206
355
 
207
356
  * Don't fetch parent of nested resource if *_id parameter is missing so it works with shallow nested routes - see issue #14
208
357
 
358
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/1.0.0...1.0.1]
359
+
209
360
 
210
361
  1.0.0 (Dec 13, 2009)
211
362
 
@@ -221,6 +372,8 @@
221
372
 
222
373
  * BACKWARDS INCOMPATIBLE: turning load and authorize resource methods into class methods which set up the before filter so they can accept additional arguments.
223
374
 
375
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/0.2.1...1.0.0]
376
+
224
377
 
225
378
  0.2.1 (Nov 26, 2009)
226
379
 
@@ -230,6 +383,8 @@
230
383
 
231
384
  * support custom objects (usually symbols) in can definition - see issue #8
232
385
 
386
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/0.2.0...0.2.1]
387
+
233
388
 
234
389
  0.2.0 (Nov 17, 2009)
235
390
 
@@ -241,6 +396,8 @@
241
396
 
242
397
  * BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to set up abilities - see issue #4
243
398
 
399
+ * {see the full list of changes}[https://github.com/ryanb/cancan/compare/0.1.0...0.2.0]
400
+
244
401
 
245
402
  0.1.0 (Nov 16, 2009)
246
403
 
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,11 @@
1
+ ### Please read before contributing
2
+
3
+ 1) If you have any questions about CanCan, search the [Wiki](https://github.com/ryanb/cancan/wiki) or use [Stack Overflow](http://stackoverflow.com/questions/tagged/cancan). Do not post questions here.
4
+
5
+ 2) If you find a security bug, **DO NOT** submit an issue here. Please send an e-mail to [ryan@railscasts.com](mailto:ryan@railscasts.com) instead.
6
+
7
+ 3) Do a small search on the issues tracker before submitting your issue to see if it was already reported / fixed. In case it was not, create your report including Rails and CanCan versions. If you are getting exceptions, please include the full backtrace.
8
+
9
+ That's it! The more information you give, the more easy it becomes for us to track it down and fix it. Ideal scenario would be adding the issue to CanCan test suite or to a sample application.
10
+
11
+ Thanks!
data/Gemfile CHANGED
@@ -3,8 +3,8 @@ source "http://rubygems.org"
3
3
  case ENV["MODEL_ADAPTER"]
4
4
  when nil, "active_record"
5
5
  gem "sqlite3"
6
- gem "activerecord", :require => "active_record"
7
- gem "with_model"
6
+ gem "activerecord", '~> 3.0.9', :require => "active_record"
7
+ gem "with_model", "~> 0.2.5"
8
8
  gem "meta_where"
9
9
  when "data_mapper"
10
10
  gem "dm-core", "~> 1.0.2"
data/README.rdoc CHANGED
@@ -1,4 +1,4 @@
1
- = CanCan
1
+ = CanCan {<img src="https://fury-badge.herokuapp.com/rb/cancan.png" alt="Gem Version" />}[http://badge.fury.io/rb/cancan] {<img src="https://secure.travis-ci.org/ryanb/cancan.png?branch=master" />}[http://travis-ci.org/ryanb/cancan] {<img src="https://codeclimate.com/badge.png" />}[https://codeclimate.com/github/ryanb/cancan]
2
2
 
3
3
  Wiki[https://github.com/ryanb/cancan/wiki] | RDocs[http://rdoc.info/projects/ryanb/cancan] | Screencast[http://railscasts.com/episodes/192-authorization-with-cancan]
4
4
 
@@ -31,6 +31,15 @@ User permissions are defined in an +Ability+ class. CanCan 1.5 includes a Rails
31
31
 
32
32
  rails g cancan:ability
33
33
 
34
+ In Rails 2.3, just add a new class in `app/models/ability.rb` with the folowing contents:
35
+
36
+ class Ability
37
+ include CanCan::Ability
38
+
39
+ def initialize(user)
40
+ end
41
+ end
42
+
34
43
  See {Defining Abilities}[https://github.com/ryanb/cancan/wiki/defining-abilities] for details.
35
44
 
36
45
 
@@ -172,10 +172,16 @@ module CanCan
172
172
  # This way one can use params[:action] in the controller to determine the permission.
173
173
  def alias_action(*args)
174
174
  target = args.pop[:to]
175
+ validate_target(target)
175
176
  aliased_actions[target] ||= []
176
177
  aliased_actions[target] += args
177
178
  end
178
179
 
180
+ # User shouldn't specify targets with names of real actions or it will cause Seg fault
181
+ def validate_target(target)
182
+ raise Error, "You can't specify target (#{target}) as alias because it is real action name" if aliased_actions.values.flatten.include? target
183
+ end
184
+
179
185
  # Returns a hash of aliased actions. The key is the target and the value is an array of actions aliasing the key.
180
186
  def aliased_actions
181
187
  @aliased_actions ||= default_alias_actions
@@ -201,6 +207,7 @@ module CanCan
201
207
  message ||= unauthorized_message(action, subject)
202
208
  raise AccessDenied.new(message, action, subject)
203
209
  end
210
+ subject
204
211
  end
205
212
 
206
213
  def unauthorized_message(action, subject)
@@ -227,6 +234,13 @@ module CanCan
227
234
  relevant_rules(action, subject).any?(&:only_raw_sql?)
228
235
  end
229
236
 
237
+ def merge(ability)
238
+ ability.send(:rules).each do |rule|
239
+ rules << rule.dup
240
+ end
241
+ self
242
+ end
243
+
230
244
  private
231
245
 
232
246
  def unauthorized_message_keys(action, subject)
@@ -94,7 +94,12 @@ module CanCan
94
94
  # [:+find_by+]
95
95
  # Find using a different attribute other than id. For example.
96
96
  #
97
- # load_resource :find_by => :permalink # will use find_by_permlink!(params[:id])
97
+ # load_resource :find_by => :permalink # will use find_by_permalink!(params[:id])
98
+ #
99
+ # [:+id_param+]
100
+ # Find using a param key other than :id. For example:
101
+ #
102
+ # load_resource :id_key => :url # will use find(params[:url])
98
103
  #
99
104
  # [:+collection+]
100
105
  # Specify which actions are resource collection actions in addition to :+index+. This
@@ -151,6 +156,9 @@ module CanCan
151
156
  # [:+except+]
152
157
  # Does not apply before filter to given actions.
153
158
  #
159
+ # [:+singleton+]
160
+ # Pass +true+ if this is a singleton resource through a +has_one+ association.
161
+ #
154
162
  # [:+parent+]
155
163
  # True or false depending on if the resource is considered a parent resource. This defaults to +true+ if a resource
156
164
  # name is given which does not match the controller.
@@ -186,7 +194,7 @@ module CanCan
186
194
  skip_authorize_resource(*args)
187
195
  end
188
196
 
189
- # Skip both the loading behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
197
+ # Skip the loading behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
190
198
  # only do authorization on certain actions. You can pass :only and :except options to specify which actions to
191
199
  # skip the effects on. It will apply to all actions by default.
192
200
  #
@@ -202,7 +210,7 @@ module CanCan
202
210
  cancan_skipper[:load][name] = options
203
211
  end
204
212
 
205
- # Skip both the authorization behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
213
+ # Skip the authorization behavior of CanCan. This is useful when using +load_and_authorize_resource+ but want to
206
214
  # only do loading on certain actions. You can pass :only and :except options to specify which actions to
207
215
  # skip the effects on. It will apply to all actions by default.
208
216
  #
@@ -247,9 +255,9 @@ module CanCan
247
255
  #
248
256
  def check_authorization(options = {})
249
257
  self.after_filter(options.slice(:only, :except)) do |controller|
250
- return if controller.instance_variable_defined?(:@_authorized)
251
- return if options[:if] && !controller.send(options[:if])
252
- return if options[:unless] && controller.send(options[:unless])
258
+ next if controller.instance_variable_defined?(:@_authorized)
259
+ next if options[:if] && !controller.send(options[:if])
260
+ next if options[:unless] && controller.send(options[:unless])
253
261
  raise AuthorizationNotPerformed, "This action failed the check_authorization because it does not authorize_resource. Add skip_authorization_check to bypass this check."
254
262
  end
255
263
  end
@@ -286,7 +294,7 @@ module CanCan
286
294
 
287
295
  def self.included(base)
288
296
  base.extend ClassMethods
289
- base.helper_method :can?, :cannot?
297
+ base.helper_method :can?, :cannot?, :current_ability
290
298
  end
291
299
 
292
300
  # Raises a CanCan::AccessDenied exception if the current_ability cannot
@@ -382,7 +390,7 @@ module CanCan
382
390
  end
383
391
  end
384
392
 
385
- if defined? ActionController
393
+ if defined? ActionController::Base
386
394
  ActionController::Base.class_eval do
387
395
  include CanCan::ControllerAdditions
388
396
  end
@@ -6,8 +6,8 @@ module CanCan
6
6
  options = args.extract_options!
7
7
  resource_name = args.first
8
8
  before_filter_method = options.delete(:prepend) ? :prepend_before_filter : :before_filter
9
- controller_class.send(before_filter_method, options.slice(:only, :except)) do |controller|
10
- controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except)).send(method)
9
+ controller_class.send(before_filter_method, options.slice(:only, :except, :if, :unless)) do |controller|
10
+ controller.class.cancan_resource_class.new(controller, resource_name, options.except(:only, :except, :if, :unless)).send(method)
11
11
  end
12
12
  end
13
13
 
@@ -82,38 +82,60 @@ module CanCan
82
82
  end
83
83
 
84
84
  def build_resource
85
- method_name = @options[:singleton] && resource_base.respond_to?("build_#{name}") ? "build_#{name}" : "new"
86
- resource = resource_base.send(method_name, @params[name] || {})
87
- initial_attributes.each do |name, value|
88
- resource.send("#{name}=", value)
85
+ resource = resource_base.new(resource_params || {})
86
+ assign_attributes(resource)
87
+ end
88
+
89
+ def assign_attributes(resource)
90
+ resource.send("#{parent_name}=", parent_resource) if @options[:singleton] && parent_resource
91
+ initial_attributes.each do |attr_name, value|
92
+ resource.send("#{attr_name}=", value)
89
93
  end
90
94
  resource
91
95
  end
92
96
 
93
97
  def initial_attributes
94
98
  current_ability.attributes_for(@params[:action].to_sym, resource_class).delete_if do |key, value|
95
- @params[name] && @params[name].include?(key)
99
+ resource_params && resource_params.include?(key)
96
100
  end
97
101
  end
98
102
 
99
103
  def find_resource
100
- if @options[:singleton] && resource_base.respond_to?(name)
101
- resource_base.send(name)
104
+ if @options[:singleton] && parent_resource.respond_to?(name)
105
+ parent_resource.send(name)
102
106
  else
103
- @options[:find_by] ? resource_base.send("find_by_#{@options[:find_by]}!", id_param) : resource_base.find(id_param)
107
+ if @options[:find_by]
108
+ if resource_base.respond_to? "find_by_#{@options[:find_by]}!"
109
+ resource_base.send("find_by_#{@options[:find_by]}!", id_param)
110
+ elsif resource_base.respond_to? "find_by"
111
+ resource_base.send("find_by", { @options[:find_by].to_sym => id_param })
112
+ else
113
+ resource_base.send(@options[:find_by], id_param)
114
+ end
115
+ else
116
+ adapter.find(resource_base, id_param)
117
+ end
104
118
  end
105
119
  end
106
120
 
121
+ def adapter
122
+ ModelAdapters::AbstractAdapter.adapter_class(resource_class)
123
+ end
124
+
107
125
  def authorization_action
108
- parent? ? :read : @params[:action].to_sym
126
+ parent? ? :show : @params[:action].to_sym
109
127
  end
110
128
 
111
129
  def id_param
112
- @params[parent? ? :"#{name}_id" : :id]
130
+ if @options[:id_param]
131
+ @params[@options[:id_param]]
132
+ else
133
+ @params[parent? ? :"#{name}_id" : :id]
134
+ end.to_s
113
135
  end
114
136
 
115
137
  def member_action?
116
- new_actions.include?(@params[:action].to_sym) || (@params[:id] && !collection_actions.include?(@params[:action].to_sym))
138
+ new_actions.include?(@params[:action].to_sym) || @options[:singleton] || ( (@params[:id] || @params[@options[:id_param]]) && !collection_actions.include?(@params[:action].to_sym))
117
139
  end
118
140
 
119
141
  # Returns the class used for this resource. This can be overriden by the :class option.
@@ -122,7 +144,7 @@ module CanCan
122
144
  def resource_class
123
145
  case @options[:class]
124
146
  when false then name.to_sym
125
- when nil then name.to_s.camelize.constantize
147
+ when nil then namespaced_name.to_s.camelize.constantize
126
148
  when String then @options[:class].constantize
127
149
  else @options[:class]
128
150
  end
@@ -155,26 +177,30 @@ module CanCan
155
177
  def resource_base
156
178
  if @options[:through]
157
179
  if parent_resource
158
- @options[:singleton] ? parent_resource : parent_resource.send(@options[:through_association] || name.to_s.pluralize)
180
+ @options[:singleton] ? resource_class : parent_resource.send(@options[:through_association] || name.to_s.pluralize)
159
181
  elsif @options[:shallow]
160
182
  resource_class
161
183
  else
162
- raise AccessDenied # maybe this should be a record not found error instead?
184
+ raise AccessDenied.new(nil, authorization_action, resource_class) # maybe this should be a record not found error instead?
163
185
  end
164
186
  else
165
187
  resource_class
166
188
  end
167
189
  end
168
190
 
191
+ def parent_name
192
+ @options[:through] && [@options[:through]].flatten.detect { |i| fetch_parent(i) }
193
+ end
194
+
169
195
  # The object to load this resource through.
170
196
  def parent_resource
171
- @options[:through] && [@options[:through]].flatten.map { |i| fetch_parent(i) }.compact.first
197
+ parent_name && fetch_parent(parent_name)
172
198
  end
173
199
 
174
200
  def fetch_parent(name)
175
201
  if @controller.instance_variable_defined? "@#{name}"
176
202
  @controller.instance_variable_get("@#{name}")
177
- elsif @controller.respond_to? name
203
+ elsif @controller.respond_to?(name, true)
178
204
  @controller.send(name)
179
205
  end
180
206
  end
@@ -187,6 +213,29 @@ module CanCan
187
213
  @name || name_from_controller
188
214
  end
189
215
 
216
+ def resource_params
217
+ if @options[:class]
218
+ params_key = extract_key(@options[:class])
219
+ return @params[params_key] if @params[params_key]
220
+ end
221
+
222
+ resource_params_by_namespaced_name
223
+ end
224
+
225
+ def resource_params_by_namespaced_name
226
+ @params[extract_key(namespaced_name)]
227
+ end
228
+
229
+ def namespace
230
+ @params[:controller].split(/::|\//)[0..-2]
231
+ end
232
+
233
+ def namespaced_name
234
+ [namespace, name.camelize].join('::').singularize.camelize.constantize
235
+ rescue NameError
236
+ name
237
+ end
238
+
190
239
  def name_from_controller
191
240
  @params[:controller].sub("Controller", "").underscore.split('/').last.singularize
192
241
  end
@@ -202,5 +251,11 @@ module CanCan
202
251
  def new_actions
203
252
  [:new, :create] + [@options[:new]].flatten
204
253
  end
254
+
255
+ private
256
+
257
+ def extract_key(value)
258
+ value.to_s.underscore.gsub('/', '_')
259
+ end
205
260
  end
206
261
  end
@@ -40,7 +40,7 @@ module CanCan
40
40
  @message = message
41
41
  @action = action
42
42
  @subject = subject
43
- @default_message = "You are not authorized to access this page."
43
+ @default_message = I18n.t(:"unauthorized.default", :default => "You are not authorized to access this page.")
44
44
  end
45
45
 
46
46
  def to_s
@@ -6,14 +6,15 @@ module CanCan
6
6
  @controller.send :association_chain
7
7
  @controller.instance_variable_get("@#{instance_name}")
8
8
  elsif new_actions.include? @params[:action].to_sym
9
- @controller.send :build_resource
9
+ resource = @controller.send :build_resource
10
+ assign_attributes(resource)
10
11
  else
11
12
  @controller.send :resource
12
13
  end
13
14
  end
14
15
 
15
16
  def resource_base
16
- @controller.send :collection
17
+ @controller.send :end_of_association_chain
17
18
  end
18
19
  end
19
20
  end
@@ -1,5 +1,5 @@
1
- RSpec = Spec unless defined? RSpec # for RSpec 1 compatability
2
- RSpec::Matchers.define :be_able_to do |*args|
1
+ rspec_module = defined?(RSpec::Core) ? 'RSpec' : 'Spec' # for RSpec 1 compatability
2
+ Kernel.const_get(rspec_module)::Matchers.define :be_able_to do |*args|
3
3
  match do |ability|
4
4
  ability.can?(*args)
5
5
  end
@@ -15,6 +15,11 @@ module CanCan
15
15
  false # override in subclass
16
16
  end
17
17
 
18
+ # Override if you need custom find behavior
19
+ def self.find(model_class, id)
20
+ model_class.find(id)
21
+ end
22
+
18
23
  # Used to determine if this model adapter will override the matching behavior for a hash of conditions.
19
24
  # If this returns true then matches_conditions_hash? will be called. See Rule#matches_conditions_hash
20
25
  def self.override_conditions_hash_matching?(subject, conditions)