canard 0.5.0.pre → 0.6.0.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +5 -5
  2. data/.hound.yml +3 -0
  3. data/.rubocop.yml +27 -0
  4. data/.rubocop_todo.yml +37 -0
  5. data/.travis.yml +1 -1
  6. data/Gemfile +7 -6
  7. data/README.md +40 -37
  8. data/Rakefile +5 -2
  9. data/canard.gemspec +8 -7
  10. data/lib/ability.rb +14 -13
  11. data/lib/canard.rb +4 -2
  12. data/lib/canard/abilities.rb +7 -9
  13. data/lib/canard/adapters/active_record.rb +32 -29
  14. data/lib/canard/adapters/mongoid.rb +18 -11
  15. data/lib/canard/find_abilities.rb +8 -9
  16. data/lib/canard/railtie.rb +11 -16
  17. data/lib/canard/user_model.rb +66 -67
  18. data/lib/canard/version.rb +3 -1
  19. data/lib/generators/ability_definition.rb +16 -14
  20. data/lib/generators/canard/ability/ability_generator.rb +16 -12
  21. data/lib/generators/rspec/ability/ability_generator.rb +9 -9
  22. data/lib/tasks/canard.rake +6 -6
  23. data/test/abilities/administrators.rb +2 -2
  24. data/test/canard/abilities_test.rb +14 -21
  25. data/test/canard/ability_test.rb +40 -52
  26. data/test/canard/adapters/active_record_test.rb +71 -135
  27. data/test/canard/adapters/mongoid_test.rb +61 -132
  28. data/test/canard/canard_test.rb +8 -10
  29. data/test/canard/find_abilities_test.rb +9 -11
  30. data/test/canard/user_model_test.rb +22 -32
  31. data/test/dummy/Rakefile +3 -1
  32. data/test/dummy/app/abilities/admins.rb +4 -4
  33. data/test/dummy/app/abilities/authors.rb +3 -3
  34. data/test/dummy/app/abilities/editors.rb +2 -2
  35. data/test/dummy/app/abilities/guests.rb +3 -3
  36. data/test/dummy/app/abilities/users.rb +4 -4
  37. data/test/dummy/app/controllers/application_controller.rb +2 -0
  38. data/test/dummy/app/models/activity.rb +3 -1
  39. data/test/dummy/app/models/member.rb +3 -3
  40. data/test/dummy/app/models/mongoid_user.rb +5 -3
  41. data/test/dummy/app/models/plain_ruby_non_user.rb +2 -2
  42. data/test/dummy/app/models/plain_ruby_user.rb +3 -3
  43. data/test/dummy/app/models/post.rb +3 -1
  44. data/test/dummy/app/models/user.rb +3 -2
  45. data/test/dummy/app/models/user_without_role.rb +4 -4
  46. data/test/dummy/app/models/user_without_role_mask.rb +3 -3
  47. data/test/dummy/config.ru +3 -1
  48. data/test/dummy/config/application.rb +9 -8
  49. data/test/dummy/config/boot.rb +4 -2
  50. data/test/dummy/config/environment.rb +3 -1
  51. data/test/dummy/config/environments/development.rb +2 -0
  52. data/test/dummy/config/environments/test.rb +4 -2
  53. data/test/dummy/config/initializers/secret_token.rb +2 -0
  54. data/test/dummy/config/initializers/session_store.rb +3 -1
  55. data/test/dummy/config/initializers/wrap_parameters.rb +3 -1
  56. data/test/dummy/config/mongoid3.yml +5 -1
  57. data/test/dummy/config/routes.rb +2 -0
  58. data/test/dummy/db/migrate/20120430083231_initialize_db.rb +7 -7
  59. data/test/dummy/db/schema.rb +11 -11
  60. data/test/dummy/script/rails +4 -2
  61. data/test/support/reloadable.rb +14 -15
  62. data/test/test_helper.rb +7 -13
  63. metadata +18 -18
  64. data/test/dummy/config/mongoid2.yml +0 -9
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: cc60d17173f92f98f6d45330a03a33fd1f7b1253
4
- data.tar.gz: 4381d33e14aa4dde69a7433eb998b09a1fad5528
2
+ SHA256:
3
+ metadata.gz: dd2cdacae06bfb7da04329a17572eb17173774faba3de5349aabfc004b34990b
4
+ data.tar.gz: 2b06876131a2befb4fe9dec8831c94ef08caa93269de8060623148040316b6fa
5
5
  SHA512:
6
- metadata.gz: 476dac97c8a7588373a07f3812c4975b3330b3f815139ba96b530084d6ebd2a85c9e0cdee374bf6de6a961646bc3aa0144989f3aa22038aee6f75c6d7e0a3de5
7
- data.tar.gz: 1f3d9f6111da01e36310b343948f5b0f2eddb979810237755653033a06edbf1a7aff3fa229d1fcbf045f4451f8b2e34c6625f9ffbd1c5ed8583a6bce362437ea
6
+ metadata.gz: 9d7d6198ab5b667c344845a77f75de282a865cfe4a4b2a514051d1c128d837972df46e4be58e6cc6e69ccc5a8f71a8f6e80f3f99da3f5a4b3a9cf688545202d0
7
+ data.tar.gz: 7974d7b761eab454523ef3c6e56ee0ce4a1387d3c1662257e31c2c011602d9979a7b7f0d403cca568177f20d1c7d9c8ea813aa314a1cee65879422e74da8b854
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ config_file: .rubocop.yml
3
+
@@ -0,0 +1,27 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ Style/StringLiterals:
4
+ Enabled: true
5
+ EnforcedStyle: single_quotes
6
+ Style/MutableConstant:
7
+ Exclude:
8
+ - 'lib/seedbank/version.rb'
9
+ Lint/ScriptPermission:
10
+ Exclude:
11
+ - 'test/dummy/Rakefile'
12
+ Metrics/LineLength:
13
+ Exclude:
14
+ - 'test/**/*'
15
+ Max: 132
16
+ Metrics/BlockLength:
17
+ Exclude:
18
+ - 'test/**/*'
19
+ Naming/PredicateName:
20
+ NameWhitelist:
21
+ - 'has_roles_mask_accessors?'
22
+ Style/Documentation:
23
+ Exclude:
24
+ - 'spec/**/*'
25
+ - 'test/**/*'
26
+ - 'lib/generators/rspec/ability/ability_generator.rb'
27
+
@@ -0,0 +1,37 @@
1
+ # This configuration was generated by
2
+ # `rubocop --auto-gen-config`
3
+ # on 2019-10-02 18:57:17 +0700 using RuboCop version 0.75.0.
4
+ # The point is for the user to remove these configuration records
5
+ # one by one as the offenses are removed from the code base.
6
+ # Note that changes in the inspected code, or installation of new
7
+ # versions of RuboCop, may require this file to be generated again.
8
+
9
+ # Offense count: 4
10
+ Metrics/AbcSize:
11
+ Max: 24
12
+
13
+ # Offense count: 1
14
+ Metrics/CyclomaticComplexity:
15
+ Max: 11
16
+
17
+ # Offense count: 4
18
+ # Configuration parameters: CountComments, ExcludedMethods.
19
+ Metrics/MethodLength:
20
+ Max: 13
21
+
22
+ # Offense count: 1
23
+ Metrics/PerceivedComplexity:
24
+ Max: 12
25
+
26
+ # Offense count: 1
27
+ Style/ClassVars:
28
+ Exclude:
29
+ - 'lib/generators/ability_definition.rb'
30
+
31
+ # Offense count: 1
32
+ # Cop supports --auto-correct.
33
+ # Configuration parameters: EnforcedStyle.
34
+ # SupportedStyles: line_count_dependent, lambda, literal
35
+ Style/Lambda:
36
+ Exclude:
37
+ - 'lib/canard/adapters/mongoid.rb'
@@ -5,7 +5,7 @@ rvm:
5
5
  - 2.2
6
6
  - 2.3.3
7
7
  - 2.4.0
8
- - jruby-9.1.7.0
8
+ - jruby
9
9
  services:
10
10
  - mongodb
11
11
 
data/Gemfile CHANGED
@@ -1,4 +1,6 @@
1
- source "http://rubygems.org"
1
+ # frozen_string_literal: true
2
+
3
+ source 'http://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in canard.gemspec
4
6
  gemspec
@@ -9,16 +11,15 @@ end
9
11
 
10
12
  # for CRuby, Rubinius, including Windows and RubyInstaller
11
13
  group :development, :test do
12
-
13
- gem 'bson', "~> 1.6.4"
14
+ gem 'bson', '~> 1.6.4'
15
+ gem 'rubocop'
14
16
 
15
17
  platform :ruby, :mswin, :mingw do
16
- gem "sqlite3"
17
- gem "bson_ext", "~> 1.6.4"
18
+ gem 'bson_ext', '~> 1.6.4'
19
+ gem 'sqlite3', '~> 1.3.5'
18
20
  end
19
21
 
20
22
  platform :jruby do
21
23
  gem 'activerecord-jdbcsqlite3-adapter'
22
24
  end
23
25
  end
24
-
data/README.md CHANGED
@@ -2,10 +2,10 @@ Canard
2
2
  ======
3
3
  [![Build Status](https://travis-ci.org/james2m/canard.svg?branch=master)](https://travis-ci.org/james2m/canard)
4
4
 
5
- Canard brings CanCan and RoleModel together to make role based authorization in Rails easy. Your ability
5
+ Canard brings CanCan and RoleModel together to make role-based authorization in Rails easy. Your ability
6
6
  definitions gain their own folder and a little structure. The easiest way to get started is with the
7
7
  Canard generator. Canard progressively enhances the abilities of the model by applying role abilities on
8
- top of the models base abilities.
8
+ top of the model's base abilities.
9
9
  A User model with :admin and :manager roles would be defined:
10
10
 
11
11
  class User < ActiveRecord::Base
@@ -14,32 +14,31 @@ A User model with :admin and :manager roles would be defined:
14
14
 
15
15
  end
16
16
 
17
- If a User has both the :manager and :admin roles Canard will apply the abilities in the following order.
18
- First it will look for a users abilities, then it will look for the roles in the order they are defined e.g.
17
+ If a User has both the :manager and :admin roles, Canard looks first for user abilities. Then it will look for other roles in the order that they are defined:
19
18
 
20
19
  app/abilities/users.rb
21
20
  app/abilities/manager.rb
22
21
  app/abilities/admin.rb
23
22
 
24
- Therefore each the later abilities only need to build on their predecessors.
23
+ Therefore each of the later abilities can build on its predecessor.
25
24
 
26
25
  Usage
27
26
  =====
28
- To generate some abilities for the User.
27
+ To generate some abilities for the User:
29
28
 
30
29
  $ rails g canard:ability user can:[read,create]:[account,statement] cannot:destroy:account
31
30
  create app/abilities/users.rb
32
31
  invoke rspec
33
32
  create spec/abilities/user_spec.rb
34
33
 
35
- Generates an ability folder in Rails root and an associated spec;
34
+ This action generates an ability folder in Rails root and an associated spec:
36
35
 
37
36
  app.abilities/
38
37
  users.rb
39
38
  spec/abilities/
40
39
  users_spec.rb
41
40
 
42
- The resulting app/abilities/users.rb will look something like this;
41
+ The resulting app/abilities/users.rb will look something like this:
43
42
 
44
43
  Canard::Abilities.for(:user) do
45
44
 
@@ -49,7 +48,7 @@ The resulting app/abilities/users.rb will look something like this;
49
48
 
50
49
  end
51
50
 
52
- And it's associated test spec/abilities/users_spec.rb;
51
+ And its associated test spec/abilities/users_spec.rb will look something like this:
53
52
 
54
53
  require_relative '../spec_helper'
55
54
  require "cancan/matchers"
@@ -89,7 +88,7 @@ And it's associated test spec/abilities/users_spec.rb;
89
88
 
90
89
  end
91
90
 
92
- You can also re-use abilities defined for one role in another. This allows you to 'inherit' abilities without having to assign all of the roles to the user. To do this, pass a list of role names to the includes_abilities_of method
91
+ You can also re-use abilities defined for one role in another. This allows you to 'inherit' abilities without having to assign all of the roles to the user. To do this, pass a list of role names to the includes_abilities_of method:
93
92
 
94
93
  Canard::Abilities.for(:writer) do
95
94
 
@@ -112,48 +111,52 @@ You can also re-use abilities defined for one role in another. This allows you t
112
111
 
113
112
  end
114
113
 
115
- A user assigned the :admin role will have all of the abilities of the :writer and :reviewer, along with their own abilities without having to have those individual roles assigned to them.
114
+ A user assigned the :admin role will have all of the abilities of the :writer and :reviewer, along with their own abilities, without having to have those individual roles assigned to them.
116
115
 
117
- Now lets generate some abilities for the manager and admin.
116
+ Now let's generate some abilities for the manager and admin:
118
117
 
119
118
  $ rails g canard:ability admin can:manage:[account,statement]
120
119
  $ rails g canard:ability manager can:edit:statement
121
120
 
122
- Gives us two new sets of abilities in the abilities folder. Canard will apply these abilities by first
123
- loading the ability for the User model and then apply the abilities for each role the current user has.
121
+ This generates two new sets of abilities in the abilities folder. Canard will apply these abilities by first
122
+ loading the ability for the User model and then applying the abilities for each of the current user's roles.
124
123
 
125
124
 
126
- If there is no user (i.e. logged out) Canard creates a guest and looks for a guest ability to apply so:
125
+ If there is no user (i.e. logged out), Canard creates a guest and looks for a guest ability to apply:
127
126
 
128
127
  $ rails g canard:ability guest can:create:user
129
128
 
130
- Would generate an ability for a not logged in user to signup.
129
+ This would generate a signup ability for a user who was not logged in.
131
130
 
132
- Obviously the generators are just a starting point and should be used only to get you going. I strongly
133
- suggest that every new model you create you add to the abilities as the specs are easy to write and CanCan
131
+ Obviously the generators are just a starting point and should be used only to get you going. I strongly
132
+ suggest that you add each new model to the abilities because the specs are easy to write and CanCan
134
133
  definitions are very clear and simple.
135
134
 
136
135
  Scopes
137
136
  ======
138
- The :acts_as_user method with automatically define some named scopes for each role. For the example User model
139
- above it will define the following scopes;
137
+ The :acts_as_user method will automatically define some named scopes for each role. For the User model
138
+ above it will define the following scopes:
140
139
 
141
- User.admins:: return all the users with the admin role
142
- User.non_admins:: return all the users without the admin role
143
- User.managers:: return all the users with the manager role
144
- User.non_managers:: return all the users without the manager role
140
+ | Scope | Returns |
141
+ | ------------------- | --------------------------------------- |
142
+ | `User.admins` | all the users with the admin role |
143
+ | `User.non_admins` | all the users without the admin role |
144
+ | `User.managers` | all the users with the manager role |
145
+ | `User.non_managers` | all the users without the manager role |
145
146
 
146
- In addition to the role specific scopes it also adds some general scopes;
147
+ In addition to the role specific scopes it also adds some general scopes:
147
148
 
148
- User.with_any_role(roles):: return all the users with any of the specified roles
149
- User.with_all_roles(roles):: return only the users with all the specified roles
149
+ | Scope | Returns |
150
+ | ------------------- | --------------------------------------------- |
151
+ | `User.with_any_role(roles)` | all the users with any of the specified roles |
152
+ | `User.with_all_roles(roles)` | only the users with all the specified roles |
150
153
 
151
154
  Installation
152
155
  ============
153
156
 
154
157
  Rails 3.x, 4.x & 5.x
155
158
  --------------------
156
- Add the canard gem to your Gemfile. In Gemfile:
159
+ Add the canard gem to your Gemfile:
157
160
 
158
161
  gem "canard"
159
162
 
@@ -167,20 +170,20 @@ That's it!
167
170
  Rails 2.x
168
171
  ---------
169
172
 
170
- Sorry you are out of luck with Rails 2.x Canard has only been written and tested with Rails 3 and above.
173
+ Sorry, you are out of luck. Canard has only been written and tested with Rails 3 and above.
171
174
 
172
- Supported ORM's
175
+ Supported ORMs
173
176
  ---------------
174
177
 
175
178
  Canard is ORM agnostic. ActiveRecord and Mongoid (thanks David Butler) adapters are currently implemented.
176
- New adapters can easily be added, but you'd need to check CanCan can also support your adapter.
179
+ New adapters can easily be added, but you'd need to check to see if CanCan can also support your adapter.
177
180
 
178
181
  Further reading
179
182
  ---------------
180
183
 
181
- Canard stands on the sholders of Ryan Bates' CanCan and Martin Rehfeld's RoleModel. You can read more
184
+ Canard stands on the shoulders of Ryan Bates' CanCan and Martin Rehfeld's RoleModel. You can read more
182
185
  about defining abilities on the CanCan wiki (https://github.com/ryanb/cancan/wiki). Canard implements
183
- the Ability class for you so you don't need the boilerplate code from Ryan's example;
186
+ the Ability class for you so you don't need the boilerplate code from Ryan's example:
184
187
 
185
188
  class Ability
186
189
  include CanCan::Ability
@@ -195,13 +198,13 @@ the Ability class for you so you don't need the boilerplate code from Ryan's exa
195
198
  end
196
199
  end
197
200
 
198
- The Canard equivalent for non admins would be;
201
+ The Canard equivalent for non-admins would be:
199
202
 
200
203
  Canard::Abilities.for(:user) do
201
204
  can :read, :all
202
205
  end
203
206
 
204
- And for Admins;
207
+ And for admins:
205
208
 
206
209
  Canard::Abilities.for(:admin) do
207
210
  can :manage, :all
@@ -217,8 +220,8 @@ Note on Patches/Pull Request
217
220
  * Fork the project.
218
221
  * Make your feature addition or bug fix.
219
222
  * Add tests for it (when I have some). This is important so I don't break it in a future version unintentionally.
220
- * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but
221
- bump version in a commit by itself I can ignore it when I pull)
223
+ * Commit. Do not mess with rakefile, version, or history. (If you want to have your own version, that is fine but
224
+ bump version in a commit by itself so I can ignore it when I pull.)
222
225
  * Send me a pull request. Bonus points for topic branches.
223
226
 
224
227
  Contributors
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
- require "bundler/gem_tasks"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
2
4
  require 'rake'
3
5
  require 'rake/testtask'
4
6
 
@@ -6,6 +8,7 @@ Rake::TestTask.new(:test) do |t|
6
8
  t.libs << 'lib' << 'test'
7
9
  t.pattern = 'test/**/*_test.rb'
8
10
  t.verbose = true
11
+ t.warning = false
9
12
  end
10
13
 
11
- task :default => ["test"]
14
+ task default: ['test']
@@ -1,5 +1,6 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
3
4
  require 'canard/version'
4
5
 
5
6
  Gem::Specification.new do |s|
@@ -9,19 +10,19 @@ Gem::Specification.new do |s|
9
10
  s.authors = ['James McCarthy']
10
11
  s.email = ['james2mccarthy@gmail.com']
11
12
  s.homepage = 'https://github.com/james2m/canard'
12
- s.summary = %q{Adds role based authorisation to Rails by combining RoleModel and CanCanCan.}
13
- s.description = %q{Wraps CanCanCan and RoleModel up to make role based authorisation really easy in Rails 4+.}
13
+ s.summary = 'Adds role based authorisation to Rails by combining RoleModel and CanCanCan.'
14
+ s.description = 'Wraps CanCanCan and RoleModel up to make role based authorisation really easy in Rails 4+.'
14
15
 
15
- s.rubyforge_project = "canard"
16
+ s.rubyforge_project = 'canard'
16
17
 
17
18
  s.files = `git ls-files`.split("\n")
18
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
21
  s.require_paths = ['lib']
21
22
 
22
23
  s.add_development_dependency 'minitest', '~> 2'
23
- s.add_development_dependency 'rails', '~> 3.2.3', '>= 3.2.3'
24
24
  s.add_development_dependency 'mongoid', '~> 3.0'
25
+ s.add_development_dependency 'rails', '~> 3.2', '>= 3.2'
25
26
 
26
27
  s.requirements << "cancan's community supported Rails4+ compatible cancancan fork."
27
28
  s.add_runtime_dependency 'cancancan', '~> 1'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Canard provides a CanCan Ability class for you. The Canard Ability class
2
4
  # looks for and applies abilities for the object passed when a new Ability
3
5
  # instance is initialized.
@@ -24,7 +26,6 @@
24
26
  # created and Canard will look for a guests.rb amongst the ability definitions
25
27
  # and give the guest those abilities.
26
28
  class Ability
27
-
28
29
  include CanCan::Ability
29
30
  extend Forwardable
30
31
 
@@ -32,12 +33,18 @@ class Ability
32
33
 
33
34
  def_delegators :Canard, :ability_definitions, :ability_key
34
35
 
35
- def initialize(object=nil)
36
-
36
+ def initialize(object = nil)
37
37
  # If object has a user attribute set the user from it otherwise assume
38
38
  # this is the user.
39
39
  @user = object.respond_to?(:user) ? object.user : object
40
40
 
41
+ add_base_abilities
42
+ add_roles_abilities if @user.respond_to?(:roles)
43
+ end
44
+
45
+ protected
46
+
47
+ def add_base_abilities
41
48
  if @user
42
49
  # Add the base user abilities.
43
50
  user_class_name = String(@user.class.name)
@@ -47,24 +54,18 @@ class Ability
47
54
  @user = Object.new
48
55
  append_abilities :guest
49
56
  end
50
-
51
- # If user has roles get those abilities
52
- if @user.respond_to?(:roles)
53
- # Add roles on top of the base user abilities
54
- @user.roles.each { |role| append_abilities(role) }
55
- end
56
-
57
57
  end
58
58
 
59
- protected
59
+ def add_roles_abilities
60
+ @user.roles.each { |role| append_abilities(role) }
61
+ end
60
62
 
61
63
  def append_abilities(dirty_key)
62
64
  key = ability_key(dirty_key)
63
- instance_eval(&ability_definitions[key]) if ability_definitions.has_key?(key)
65
+ instance_eval(&ability_definitions[key]) if ability_definitions.key?(key)
64
66
  end
65
67
 
66
68
  def includes_abilities_of(*other_roles)
67
69
  other_roles.each { |other_role| append_abilities(other_role) }
68
70
  end
69
-
70
71
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
  require 'cancan'
3
5
  require 'role_model'
4
6
  require 'canard/abilities'
5
7
  require 'canard/version'
6
8
  require 'canard/user_model'
7
- require "canard/find_abilities"
8
- require "ability"
9
+ require 'canard/find_abilities'
10
+ require 'ability'
9
11
 
10
12
  require 'canard/railtie' if defined?(Rails) && Rails::VERSION::MAJOR >= 3
@@ -1,11 +1,11 @@
1
- module Canard
2
- class Abilities
1
+ # frozen_string_literal: true
3
2
 
4
- @definitions = {}
5
- @default_path = 'app/abilities'
3
+ module Canard
4
+ class Abilities # :nodoc:
5
+ @definitions = {}
6
+ @default_path = 'app/abilities'
6
7
 
7
8
  class << self
8
-
9
9
  extend Forwardable
10
10
 
11
11
  def_delegators :Canard, :ability_key
@@ -21,13 +21,11 @@ module Canard
21
21
  end
22
22
 
23
23
  def for(name, &block)
24
- raise ArgumentError.new('No block of ability definitions given') unless block_given?
24
+ raise ArgumentError, 'No block of ability definitions given' unless block_given?
25
+
25
26
  key = ability_key(name)
26
27
  @definitions[key] = block
27
28
  end
28
-
29
29
  end
30
-
31
30
  end
32
-
33
31
  end