cancancan-system 1.1.2 → 1.1.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aacda0bee6c9b4ee10ae3c96216d994f26ba03eb603c137751a1cf8bedeacdb0
4
- data.tar.gz: 3256c56f33c7caeb179d7aee6e4f5e6b85856ac6b3e17d728223becda81d1fcb
3
+ metadata.gz: a240cafcc8a7e32b63b9b9a3bf3c9cf6c7bffbf3584e14f561570353aa6ccd42
4
+ data.tar.gz: 672681f772283b523217f833ddf5c743954f9f4e388d791ae07f1424f7402838
5
5
  SHA512:
6
- metadata.gz: 0e2c02a9315d7084daf7ee263912b6927415f59e131a0780b180c528e3a059bedb812376e44bfa951f48e38f4de5487b9c8970dbbd2c16d68c19bc8234d32983
7
- data.tar.gz: 8a44b6a52efc878a8e01893dfb5c40f1205b5c130e982eea01163af881d32f4f21965931b276eac02547cf655ff08e4cbfcc1e2ff9bddb14fd207f3a99e1f5ff
6
+ metadata.gz: f15ec3f979e1593ce1f74240717e3a6ff2b6b90db5765fe465e37689c7622c44b1520c1d2701fd2c47c8833f1890341c6c0208b26771d0a48cf5624e099e057b
7
+ data.tar.gz: d830fcb1925a155829c6ea08b4a32f5e64572f4cfb85772c55ec16d1fa256a4be0d36203181fcabe8ead3298536cd12777a5bf64a047ca04aea7bdc860468100
data/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2018 Jonas Hübotter
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Jonas Hübotter
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md CHANGED
@@ -1,345 +1,330 @@
1
- # CanCanCan System
2
-
3
- [![Gem Version](https://badge.fury.io/rb/cancancan-system.svg)](https://badge.fury.io/rb/cancancan-system) <img src="https://travis-ci.org/jonhue/cancancan-system.svg?branch=master" />
4
-
5
- Conventions & helpers simplifying the use of CanCanCan in complex Rails applications. CanCanCan System simplifies authorizing collaborations, memberships and more across a complex structure of models.
6
-
7
- To describe complex abilities CanCanCan System relies on two different constructs: ActiveRecord **objects**, and **relationships** of users to those objects.
8
-
9
- CanCanCan System uses two attributes on *objects* to describe abilities:
10
-
11
- * **ability:** Describes the default ability of users without a special relationship with an object.
12
- * **visiblity:** Specifies whether an object is visible to other users than the creator.
13
-
14
- CanCanCan System uses one attribute on *relationships* to describe abilities:
15
-
16
- * **ability:** Describes the ability of a user with the related object.
17
-
18
- `ability` can have any CanCanCan permission, `'admin'` (`:manage`), `'user'` (`:modify`) or `'guest'` (`:read`) as value while `visiblity` is limited to `public` and `private`.
19
-
20
- ---
21
-
22
- ## Table of Contents
23
-
24
- * [Installation](#installation)
25
- * [Usage](#usage)
26
- * [Defining abilities](#defining-abilities)
27
- * [Public abilities](#public-abilities)
28
- * [acts_as_belongable abilities](#acts_as_belongable-abilities)
29
- * [Membership abilities](#membership-abilities)
30
- * [Get abilities](#get-abilities)
31
- * [To Do](#to-do)
32
- * [Contributing](#contributing)
33
- * [Contributors](#contributors)
34
- * [Semantic versioning](#semantic-versioning)
35
- * [License](#license)
36
-
37
- ---
38
-
39
- ## Installation
40
-
41
- CanCanCan System works with Rails 5 onwards. You can add it to your `Gemfile` with:
42
-
43
- ```ruby
44
- gem 'cancancan-system'
45
- ```
46
-
47
- And then execute:
48
-
49
- $ bundle
50
-
51
- Or install it yourself as:
52
-
53
- $ gem install cancancan-system
54
-
55
- If you always want to be up to date fetch the latest from GitHub in your `Gemfile`:
56
-
57
- ```ruby
58
- gem 'cancancan-system', github: 'jonhue/cancancan-system'
59
- ```
60
-
61
- Now run the generator:
62
-
63
- $ rails g cancancan_system
64
-
65
- To wrap things up, migrate the changes to your database:
66
-
67
- $ rails db:migrate
68
-
69
- ---
70
-
71
- ## Usage
72
-
73
- To get started add CanCanCan System to your `Ability` class (`app/models/ability.rb`) and add the required `:modify` alias:
74
-
75
- ```ruby
76
- class Ability
77
-
78
- include CanCan::Ability
79
- include CanCanCan::System::Ability
80
-
81
- def initialize user
82
- modify [:create, :read, :update, :destroy]
83
- end
84
-
85
- end
86
- ```
87
-
88
- **Note:** The aliases (`:create, :read, :update, :destroy`) can be custom.
89
-
90
- You should add the `ability` attribute to ActiveRecord models you want to [define abilities](#defining-abilities) for:
91
-
92
- ```ruby
93
- add_column :users, :ability, :string, default: 'guest'
94
- ```
95
-
96
- And you should add a `visiblity` attribute to ActiveRecord models you want to define [public abilities](#public-abilities) for:
97
-
98
- ```ruby
99
- add_column :users, :visiblity, :string, default: 'public'
100
- ```
101
-
102
- ### Defining Abilities
103
-
104
- CanCanCan System makes an `abilities` method available which simplifies setting up common abilities:
105
-
106
- ```ruby
107
- def initialize user
108
- abilities Post, user
109
- end
110
- ```
111
-
112
- This is equivalent to:
113
-
114
- ```ruby
115
- def initialize user
116
- public_abilities Post
117
- can :manage, Post, user_id: user.id if user
118
- end
119
- ```
120
-
121
- You can also use the `abilities` method with custom column names and polymorphic associations. This comes in handy when using the [NotificationsRails gem](https://github.com/jonhue/notifications-rails):
122
-
123
- ```ruby
124
- def initialize user
125
- abilities Notification, user, column: 'target', polymorphic: true, public_abilities: false
126
- end
127
- ```
128
-
129
- **Note:** Set `column` to `nil` or `''` to use the `id` attribute.
130
-
131
- This is equivalent to:
132
-
133
- ```ruby
134
- def initialize user
135
- can :manage, Notification, target_id: user.id, target_type: user.class.name if user
136
- end
137
- ```
138
-
139
- Learn more about the `public_abilities` method [here](#public-abilities).
140
-
141
- #### Public abilities
142
-
143
- The `public_abilities` method defines the object-abilities without a `user` being present:
144
-
145
- ```ruby
146
- def initialize user
147
- public_abilities Post
148
- end
149
- ```
150
-
151
- This is equivalent to:
152
-
153
- ```ruby
154
- def initialize user
155
- can :manage, Post, ability: 'admin', visibility: 'public'
156
- can :modify, Post, ability: 'user', visibility: 'public'
157
- can :read, Post, ability: 'guest', visibility: 'public'
158
- end
159
- ```
160
-
161
- #### acts_as_belongable abilities
162
-
163
- CanCanCan System integrates with the [acts_as_belongable gem](https://github.com/jonhue/acts_as_belongable) to make defining abilities for relationships dead simple.
164
-
165
- Let's say our users can be a member of multiple organizations:
166
-
167
- ```ruby
168
- class User < ApplicationRecord
169
- acts_as_belongable
170
- belongable :member_of_organizations, 'Organization', scope: :membership
171
- has_many :organizations
172
- end
173
-
174
- class Organization < ApplicationRecord
175
- acts_as_belonger
176
- belonger :members, 'User', scope: :membership
177
- belongs_to :user
178
- end
179
- ```
180
-
181
- We would then just do:
182
-
183
- ```ruby
184
- def initialize user
185
- abilities Organization, user do
186
- belonger_abilities Organization, user, scope: :membership
187
- end
188
- end
189
- ```
190
-
191
- **Note:** This can be done in the same way with `belongable_abilities` for `belongable` relationships.
192
-
193
- Now we are able to add members to our organizations and set their abilities:
194
-
195
- ```ruby
196
- Organization.first.add_belongable User.first, scope: :membership, ability: 'admin'
197
- ```
198
-
199
- **Note:** The `scope` option is optional. If omitted, the defined abilities will apply to all belongings regardless of their scope.
200
-
201
- #### Membership abilities
202
-
203
- Now, let us assume that we have another model: `Post`.
204
-
205
- ```ruby
206
- class User < ApplicationRecord
207
- acts_as_belongable
208
- belongable :member_of_organizations, 'Organization', scope: :membership
209
- has_many :posts
210
- has_many :organizations
211
- end
212
-
213
- class Organization < ApplicationRecord
214
- acts_as_belonger
215
- belonger :members, 'User', scope: :membership
216
- has_many :posts
217
- belongs_to :user
218
- end
219
-
220
- class Post < ApplicationRecord
221
- belongs_to :user
222
- belongs_to :organization
223
- end
224
- ```
225
-
226
- You want the posts of an organization to be accessible for its members. It doesn't get any simpler than this:
227
-
228
- ```ruby
229
- def initialize user
230
- abilities Post, user do
231
- membership_abilities 'Organization', Post, user, scope: :membership
232
- end
233
- end
234
- ```
235
-
236
- **Note:** The `scope` option is optional. If omitted, the defined abilities will apply to all belongings regardless of their scope.
237
-
238
- You are also able to perform some customization:
239
-
240
- ```ruby
241
- class Post < ApplicationRecord
242
- belongs_to :user
243
- belongs_to :object, polymorphic: true
244
- end
245
- ```
246
-
247
- ```ruby
248
- def initialize user
249
- abilities Post, user do
250
- membership_abilities 'Organization', Post, user, scope: :membership, column: 'object', polymorphic: true
251
- end
252
- end
253
- ```
254
-
255
- Another option is to use the [acts_as_belongable gem](https://github.com/jonhue/acts_as_belongable) to associate posts with organizations:
256
-
257
- ```ruby
258
- class Organization < ApplicationRecord
259
- acts_as_belonger
260
- belonger :members, 'User', scope: :membership
261
- belonger :posts, 'Post'
262
- has_many :posts
263
- belongs_to :user
264
- end
265
-
266
- class Post < ApplicationRecord
267
- acts_as_belongable
268
- belongable :organizations, 'Organization'
269
- belongs_to :user
270
- end
271
- ```
272
-
273
- ```ruby
274
- def initialize user
275
- abilities Post, user do
276
- organization_abilities Post, user, scope: :membership, acts_as_belongable: true
277
- end
278
- end
279
- ```
280
-
281
- **Note:** If your `acts_as_belongable` association in the `Post` model is not following the CanCanCan System naming convention, you can override it by passing the `column` option.
282
-
283
- ### Get abilities
284
-
285
- You can use the `ability` method to get the ability of an ActiveRecord object:
286
-
287
- ```ruby
288
- Organization.first.ability
289
- # => 'guest'
290
-
291
- ability Organization.first
292
- # => :read
293
- ```
294
-
295
- It returns a symbol or `nil`.
296
-
297
- ---
298
-
299
- ## To Do
300
-
301
- [Here](https://github.com/jonhue/cancancan-system/projects/1) is the full list of current projects.
302
-
303
- To propose your ideas, initiate the discussion by adding a [new issue](https://github.com/jonhue/cancancan-system/issues/new).
304
-
305
- ---
306
-
307
- ## Contributing
308
-
309
- We hope that you will consider contributing to CanCanCan System. Please read this short overview for some information about how to get started:
310
-
311
- [Learn more about contributing to this repository](CONTRIBUTING.md), [Code of Conduct](CODE_OF_CONDUCT.md)
312
-
313
- ### Contributors
314
-
315
- Give the people some :heart: who are working on this project. See them all at:
316
-
317
- https://github.com/jonhue/cancancan-system/graphs/contributors
318
-
319
- ### Semantic Versioning
320
-
321
- CanCanCan System follows Semantic Versioning 2.0 as defined at http://semver.org.
322
-
323
- ## License
324
-
325
- MIT License
326
-
327
- Copyright (c) 2018 Jonas Hübotter
328
-
329
- Permission is hereby granted, free of charge, to any person obtaining a copy
330
- of this software and associated documentation files (the "Software"), to deal
331
- in the Software without restriction, including without limitation the rights
332
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
333
- copies of the Software, and to permit persons to whom the Software is
334
- furnished to do so, subject to the following conditions:
335
-
336
- The above copyright notice and this permission notice shall be included in all
337
- copies or substantial portions of the Software.
338
-
339
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
340
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
341
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
342
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
343
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
344
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
345
- SOFTWARE.
1
+ # CanCanCan System
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/cancancan-system.svg)](https://badge.fury.io/rb/cancancan-system) ![Travis](https://travis-ci.org/jonhue/cancancan-system.svg?branch=master)
4
+
5
+ Conventions & helpers simplifying the use of CanCanCan in complex Rails applications. CanCanCan System simplifies authorizing collaborations, memberships and more across a complex structure of models.
6
+
7
+ To describe complex abilities CanCanCan System relies on two different constructs: ActiveRecord **objects**, and **relationships** of users to those objects.
8
+
9
+ CanCanCan System uses two attributes on *objects* to describe abilities:
10
+
11
+ * **ability:** Describes the default ability of users without a special relationship with an object.
12
+ * **visiblity:** Specifies whether an object is visible to other users than the creator.
13
+
14
+ CanCanCan System uses one attribute on *relationships* to describe abilities:
15
+
16
+ * **ability:** Describes the ability of a user with the related object.
17
+
18
+ `ability` can have any CanCanCan permission, `'admin'` (`:manage`), `'user'` (`:modify`) or `'guest'` (`:read`) as value while `visiblity` is limited to `public` and `private`.
19
+
20
+ ---
21
+
22
+ ## Table of Contents
23
+
24
+ * [Installation](#installation)
25
+ * [Usage](#usage)
26
+ * [Defining abilities](#defining-abilities)
27
+ * [Public abilities](#public-abilities)
28
+ * [acts_as_belongable abilities](#acts_as_belongable-abilities)
29
+ * [Membership abilities](#membership-abilities)
30
+ * [Get abilities](#get-abilities)
31
+ * [Testing](#testing)
32
+ * [To Do](#to-do)
33
+ * [Contributing](#contributing)
34
+ * [Semantic versioning](#semantic-versioning)
35
+
36
+ ---
37
+
38
+ ## Installation
39
+
40
+ CanCanCan System works with Rails 5 onwards. You can add it to your `Gemfile` with:
41
+
42
+ ```ruby
43
+ gem 'cancancan-system'
44
+ ```
45
+
46
+ And then execute:
47
+
48
+ $ bundle
49
+
50
+ Or install it yourself as:
51
+
52
+ $ gem install cancancan-system
53
+
54
+ If you always want to be up to date fetch the latest from GitHub in your `Gemfile`:
55
+
56
+ ```ruby
57
+ gem 'cancancan-system', github: 'jonhue/cancancan-system'
58
+ ```
59
+
60
+ Now run the generator:
61
+
62
+ $ rails g cancancan_system
63
+
64
+ To wrap things up, migrate the changes to your database:
65
+
66
+ $ rails db:migrate
67
+
68
+ ---
69
+
70
+ ## Usage
71
+
72
+ To get started add CanCanCan System to your `Ability` class (`app/models/ability.rb`) and add the required `:modify` alias:
73
+
74
+ ```ruby
75
+ class Ability
76
+ include CanCan::Ability
77
+ include CanCanCan::System::Ability
78
+
79
+ def initialize(user)
80
+ modify([:create, :read, :update, :destroy])
81
+ end
82
+ end
83
+ ```
84
+
85
+ **Note:** The aliases (`:create, :read, :update, :destroy`) can be custom.
86
+
87
+ You should add the `ability` attribute to ActiveRecord models you want to [define abilities](#defining-abilities) for:
88
+
89
+ ```ruby
90
+ add_column :users, :ability, :string, default: 'guest'
91
+ ```
92
+
93
+ And you should add a `visiblity` attribute to ActiveRecord models you want to define [public abilities](#public-abilities) for:
94
+
95
+ ```ruby
96
+ add_column :users, :visiblity, :string, default: 'public'
97
+ ```
98
+
99
+ ### Defining Abilities
100
+
101
+ CanCanCan System makes an `abilities` method available which simplifies setting up common abilities:
102
+
103
+ ```ruby
104
+ def initialize(user)
105
+ abilities(Post, user)
106
+ end
107
+ ```
108
+
109
+ This is equivalent to:
110
+
111
+ ```ruby
112
+ def initialize(user)
113
+ public_abilities(Post)
114
+ can(:manage, Post, user_id: user.id) if user
115
+ end
116
+ ```
117
+
118
+ You can also use the `abilities` method with custom column names and polymorphic associations. This comes in handy when using the [NotificationsRails gem](https://github.com/jonhue/notifications-rails):
119
+
120
+ ```ruby
121
+ def initialize(user)
122
+ abilities(Notification, user, column: 'target', polymorphic: true, public_abilities: false)
123
+ end
124
+ ```
125
+
126
+ **Note:** Set `column` to `nil` or `''` to use the `id` attribute.
127
+
128
+ This is equivalent to:
129
+
130
+ ```ruby
131
+ def initialize(user)
132
+ can(:manage, Notification, target_id: user.id, target_type: user.class.name) if user
133
+ end
134
+ ```
135
+
136
+ Learn more about the `public_abilities` method [here](#public-abilities).
137
+
138
+ #### Public abilities
139
+
140
+ The `public_abilities` method defines the object-abilities without a `user` being present:
141
+
142
+ ```ruby
143
+ def initialize(user)
144
+ public_abilities(Post)
145
+ end
146
+ ```
147
+
148
+ This is equivalent to:
149
+
150
+ ```ruby
151
+ def initialize(user)
152
+ can(:manage, Post, ability: 'admin', visibility: 'public')
153
+ can(:modify, Post, ability: 'user', visibility: 'public')
154
+ can(:read, Post, ability: 'guest', visibility: 'public')
155
+ end
156
+ ```
157
+
158
+ #### acts_as_belongable abilities
159
+
160
+ CanCanCan System integrates with the [acts_as_belongable gem](https://github.com/jonhue/acts_as_belongable) to make defining abilities for relationships dead simple.
161
+
162
+ Let's say our users can be a member of multiple organizations:
163
+
164
+ ```ruby
165
+ class User < ApplicationRecord
166
+ acts_as_belongable
167
+ belongable :member_of_organizations, 'Organization', scope: :membership
168
+ has_many :organizations
169
+ end
170
+
171
+ class Organization < ApplicationRecord
172
+ acts_as_belonger
173
+ belonger :members, 'User', scope: :membership
174
+ belongs_to :user
175
+ end
176
+ ```
177
+
178
+ We would then just do:
179
+
180
+ ```ruby
181
+ def initialize(user)
182
+ abilities(Organization, user) do
183
+ belonger_abilities(Organization, user, scope: :membership)
184
+ end
185
+ end
186
+ ```
187
+
188
+ **Note:** This can be done in the same way with `belongable_abilities` for `belongable` relationships.
189
+
190
+ Now we are able to add members to our organizations and set their abilities:
191
+
192
+ ```ruby
193
+ Organization.first.add_belongable(User.first, scope: :membership, ability: 'admin')
194
+ ```
195
+
196
+ **Note:** The `scope` option is optional. If omitted, the defined abilities will apply to all belongings regardless of their scope.
197
+
198
+ #### Membership abilities
199
+
200
+ Now, let us assume that we have another model: `Post`.
201
+
202
+ ```ruby
203
+ class User < ApplicationRecord
204
+ acts_as_belongable
205
+ belongable :member_of_organizations, 'Organization', scope: :membership
206
+ has_many :posts
207
+ has_many :organizations
208
+ end
209
+
210
+ class Organization < ApplicationRecord
211
+ acts_as_belonger
212
+ belonger :members, 'User', scope: :membership
213
+ has_many :posts
214
+ belongs_to :user
215
+ end
216
+
217
+ class Post < ApplicationRecord
218
+ belongs_to :user
219
+ belongs_to :organization
220
+ end
221
+ ```
222
+
223
+ You want the posts of an organization to be accessible for its members. It doesn't get any simpler than this:
224
+
225
+ ```ruby
226
+ def initialize(user)
227
+ abilities(Post, user) do
228
+ membership_abilities('Organization', Post, user, scope: :membership)
229
+ end
230
+ end
231
+ ```
232
+
233
+ **Note:** The `scope` option is optional. If omitted, the defined abilities will apply to all belongings regardless of their scope.
234
+
235
+ You are also able to perform some customization:
236
+
237
+ ```ruby
238
+ class Post < ApplicationRecord
239
+ belongs_to :user
240
+ belongs_to :object, polymorphic: true
241
+ end
242
+ ```
243
+
244
+ ```ruby
245
+ def initialize(user)
246
+ abilities(Post, user) do
247
+ membership_abilities('Organization', Post, user, scope: :membership, column: 'object', polymorphic: true)
248
+ end
249
+ end
250
+ ```
251
+
252
+ Another option is to use the [acts_as_belongable gem](https://github.com/jonhue/acts_as_belongable) to associate posts with organizations:
253
+
254
+ ```ruby
255
+ class Organization < ApplicationRecord
256
+ acts_as_belonger
257
+ belonger :members, 'User', scope: :membership
258
+ belonger :posts, 'Post'
259
+ has_many :posts
260
+ belongs_to :user
261
+ end
262
+
263
+ class Post < ApplicationRecord
264
+ acts_as_belongable
265
+ belongable :organizations, 'Organization'
266
+ belongs_to :user
267
+ end
268
+ ```
269
+
270
+ ```ruby
271
+ def initialize(user)
272
+ abilities(Post, user) do
273
+ organization_abilities(Post, user, scope: :membership, acts_as_belongable: true)
274
+ end
275
+ end
276
+ ```
277
+
278
+ **Note:** If your `acts_as_belongable` association in the `Post` model is not following the CanCanCan System naming convention, you can override it by passing the `column` option.
279
+
280
+ ### Get abilities
281
+
282
+ You can use the `ability` method to get the ability of an ActiveRecord object:
283
+
284
+ ```ruby
285
+ Organization.first.ability
286
+ # => 'guest'
287
+
288
+ ability(Organization.first)
289
+ # => :read
290
+ ```
291
+
292
+ It returns a symbol or `nil`.
293
+
294
+ ---
295
+
296
+ ## Testing
297
+
298
+ 1. Fork this repository
299
+ 2. Clone your forked git locally
300
+ 3. Install dependencies
301
+
302
+ `$ bundle install`
303
+
304
+ 4. Run specs
305
+
306
+ `$ bundle exec rspec`
307
+
308
+ 5. Run RuboCop
309
+
310
+ `$ bundle exec rubocop`
311
+
312
+ ---
313
+
314
+ ## To Do
315
+
316
+ We use [GitHub projects](https://github.com/jonhue/cancancan-system/projects/1) to coordinate the work on this project.
317
+
318
+ To propose your ideas, initiate the discussion by adding a [new issue](https://github.com/jonhue/cancancan-system/issues/new).
319
+
320
+ ---
321
+
322
+ ## Contributing
323
+
324
+ We hope that you will consider contributing to CanCanCan System. Please read this short overview for some information about how to get started:
325
+
326
+ [Learn more about contributing to this repository](CONTRIBUTING.md), [Code of Conduct](CODE_OF_CONDUCT.md)
327
+
328
+ ### Semantic Versioning
329
+
330
+ CanCanCan System follows Semantic Versioning 2.0 as defined at http://semver.org.