consul 1.3.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.8-0.lock ADDED
@@ -0,0 +1,174 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ consul (2.0.0)
5
+ activerecord (>= 6.0)
6
+ activesupport (>= 6.0)
7
+ edge_rider (>= 0.3.0)
8
+ memoized (>= 1.0.2)
9
+ railties (>= 6.0)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ actionpack (8.0.1)
15
+ actionview (= 8.0.1)
16
+ activesupport (= 8.0.1)
17
+ nokogiri (>= 1.8.5)
18
+ rack (>= 2.2.4)
19
+ rack-session (>= 1.0.1)
20
+ rack-test (>= 0.6.3)
21
+ rails-dom-testing (~> 2.2)
22
+ rails-html-sanitizer (~> 1.6)
23
+ useragent (~> 0.16)
24
+ actionview (8.0.1)
25
+ activesupport (= 8.0.1)
26
+ builder (~> 3.1)
27
+ erubi (~> 1.11)
28
+ rails-dom-testing (~> 2.2)
29
+ rails-html-sanitizer (~> 1.6)
30
+ activemodel (8.0.1)
31
+ activesupport (= 8.0.1)
32
+ activerecord (8.0.1)
33
+ activemodel (= 8.0.1)
34
+ activesupport (= 8.0.1)
35
+ timeout (>= 0.4.0)
36
+ activesupport (8.0.1)
37
+ base64
38
+ benchmark (>= 0.3)
39
+ bigdecimal
40
+ concurrent-ruby (~> 1.0, >= 1.3.1)
41
+ connection_pool (>= 2.2.5)
42
+ drb
43
+ i18n (>= 1.6, < 2)
44
+ logger (>= 1.4.2)
45
+ minitest (>= 5.1)
46
+ securerandom (>= 0.3)
47
+ tzinfo (~> 2.0, >= 2.0.5)
48
+ uri (>= 0.13.1)
49
+ assignable_values (1.0.0)
50
+ activerecord (>= 2.3)
51
+ base64 (0.2.0)
52
+ benchmark (0.4.0)
53
+ bigdecimal (3.1.8)
54
+ builder (3.3.0)
55
+ concurrent-ruby (1.3.3)
56
+ connection_pool (2.4.1)
57
+ crass (1.0.6)
58
+ database_cleaner (2.0.2)
59
+ database_cleaner-active_record (>= 2, < 3)
60
+ database_cleaner-active_record (2.2.0)
61
+ activerecord (>= 5.a)
62
+ database_cleaner-core (~> 2.0.0)
63
+ database_cleaner-core (2.0.1)
64
+ date (3.4.1)
65
+ diff-lcs (1.5.1)
66
+ drb (2.2.1)
67
+ edge_rider (2.3.0)
68
+ activerecord (>= 3.2)
69
+ erubi (1.13.0)
70
+ gemika (0.8.3)
71
+ i18n (1.14.5)
72
+ concurrent-ruby (~> 1.0)
73
+ io-console (0.8.0)
74
+ irb (1.14.3)
75
+ rdoc (>= 4.0.0)
76
+ reline (>= 0.4.2)
77
+ logger (1.6.1)
78
+ loofah (2.22.0)
79
+ crass (~> 1.0.2)
80
+ nokogiri (>= 1.12.0)
81
+ memoized (1.1.1)
82
+ mini_portile2 (2.8.8)
83
+ minitest (5.24.1)
84
+ nokogiri (1.16.6)
85
+ mini_portile2 (~> 2.8.2)
86
+ racc (~> 1.4)
87
+ psych (5.2.2)
88
+ date
89
+ stringio
90
+ racc (1.8.0)
91
+ rack (3.1.7)
92
+ rack-session (2.0.0)
93
+ rack (>= 3.0.0)
94
+ rack-test (2.1.0)
95
+ rack (>= 1.3)
96
+ rackup (2.2.1)
97
+ rack (>= 3)
98
+ rails-dom-testing (2.2.0)
99
+ activesupport (>= 5.0.0)
100
+ minitest
101
+ nokogiri (>= 1.6)
102
+ rails-html-sanitizer (1.6.0)
103
+ loofah (~> 2.21)
104
+ nokogiri (~> 1.14)
105
+ railties (8.0.1)
106
+ actionpack (= 8.0.1)
107
+ activesupport (= 8.0.1)
108
+ irb (~> 1.13)
109
+ rackup (>= 1.0.0)
110
+ rake (>= 12.2)
111
+ thor (~> 1.0, >= 1.2.2)
112
+ zeitwerk (~> 2.6)
113
+ rake (13.2.1)
114
+ rdoc (6.10.0)
115
+ psych (>= 4.0.0)
116
+ reline (0.6.0)
117
+ io-console (~> 0.5)
118
+ rspec (3.13.0)
119
+ rspec-core (~> 3.13.0)
120
+ rspec-expectations (~> 3.13.0)
121
+ rspec-mocks (~> 3.13.0)
122
+ rspec-core (3.13.0)
123
+ rspec-support (~> 3.13.0)
124
+ rspec-expectations (3.13.1)
125
+ diff-lcs (>= 1.2.0, < 2.0)
126
+ rspec-support (~> 3.13.0)
127
+ rspec-mocks (3.13.1)
128
+ diff-lcs (>= 1.2.0, < 2.0)
129
+ rspec-support (~> 3.13.0)
130
+ rspec-rails (6.1.3)
131
+ actionpack (>= 6.1)
132
+ activesupport (>= 6.1)
133
+ railties (>= 6.1)
134
+ rspec-core (~> 3.13)
135
+ rspec-expectations (~> 3.13)
136
+ rspec-mocks (~> 3.13)
137
+ rspec-support (~> 3.13)
138
+ rspec-support (3.13.1)
139
+ rspec_candy (0.5.1)
140
+ rspec
141
+ sneaky-save
142
+ securerandom (0.3.2)
143
+ shoulda-matchers (6.2.0)
144
+ activesupport (>= 5.2.0)
145
+ sneaky-save (0.1.3)
146
+ activerecord (>= 3.2.0)
147
+ sqlite3 (2.4.1)
148
+ mini_portile2 (~> 2.8.0)
149
+ stringio (3.1.2)
150
+ thor (1.3.2)
151
+ timeout (0.4.1)
152
+ tzinfo (2.0.6)
153
+ concurrent-ruby (~> 1.0)
154
+ uri (1.0.2)
155
+ useragent (0.16.10)
156
+ zeitwerk (2.7.1)
157
+
158
+ PLATFORMS
159
+ ruby
160
+
161
+ DEPENDENCIES
162
+ assignable_values
163
+ consul!
164
+ database_cleaner
165
+ gemika (>= 0.8.1)
166
+ railties (~> 8.0)
167
+ rspec
168
+ rspec-rails
169
+ rspec_candy
170
+ shoulda-matchers
171
+ sqlite3
172
+
173
+ BUNDLED WITH
174
+ 2.5.15
data/Gemfile.lock CHANGED
@@ -1 +1 @@
1
- Gemfile.7-0.lock
1
+ Gemfile.8-0.lock
data/README.md CHANGED
@@ -1,19 +1,29 @@
1
- Consul — A next gen authorization solution
2
- ==========================================
3
-
4
- [![Tests](https://github.com/makandra/consul/workflows/Tests/badge.svg)](https://github.com/makandra/consul/actions) [![Code Climate](https://codeclimate.com/github/makandra/consul.png)](https://codeclimate.com/github/makandra/consul)
5
-
6
-
7
- Consul is an authorization solution for Ruby on Rails where you describe *sets of accessible things* to control what a user can see or edit.
1
+ <p>
2
+ <a href="https://makandra.de/">
3
+ <picture>
4
+ <source media="(prefers-color-scheme: light)" srcset="media/makandra-with-bottom-margin.light.svg">
5
+ <source media="(prefers-color-scheme: dark)" srcset="media/makandra-with-bottom-margin.dark.svg">
6
+ <img align="right" width="25%" alt="makandra" src="media/makandra-with-bottom-margin.light.svg">
7
+ </picture>
8
+ </a>
9
+
10
+ <picture>
11
+ <source media="(prefers-color-scheme: light)" srcset="media/logo.light.shapes.svg">
12
+ <source media="(prefers-color-scheme: dark)" srcset="media/logo.dark.shapes.svg">
13
+ <img width="155" alt="consul" role="heading" aria-level="1" src="media/logo.light.shapes.svg">
14
+ </picture>
15
+ </p>
16
+
17
+ [![Tests](https://github.com/makandra/consul/workflows/Tests/badge.svg)](https://github.com/makandra/consul/actions)
18
+
19
+ Consul is an authorization solution for Ruby on Rails where you describe _sets of accessible things_ to control what a user can see or edit.
8
20
 
9
21
  We have used Consul in combination with [assignable_values](https://github.com/makandra/assignable_values) to solve a variety of authorization requirements ranging from boring to bizarre.
10
22
  Also see our crash course video: [Solving bizare authorization requirements with Rails](http://bizarre-authorization.talks.makandra.com/).
11
23
 
12
- Consul is tested with Rails 5.2, 6.1 and 7.0 on Ruby 2.5, 2.7 and 3.0 (only if supported, for each Ruby/Rails combination). If you need support for Rails 3.2, please use [v0.13.2](https://github.com/makandra/consul/tree/v0.13.2).
24
+ Consul is tested with Rails 6.1, 7.1, 7.2 and 8.0 on Ruby 2.5, 2.7, 3.2, 3.3 (only if supported, for each Ruby/Rails combination). If you need support for Rails 3.2, please use [v0.13.2](https://github.com/makandra/consul/tree/v0.13.2).
13
25
 
14
-
15
- Describing access to your application
16
- -------------------------------------
26
+ ## Describing access to your application
17
27
 
18
28
  You describe access to your application by putting a `Power` model into `app/models/power.rb`.
19
29
  Inside your `Power` you can talk about what is accessible for the current user, e.g.
@@ -51,10 +61,8 @@ There are no restrictions on the name or constructor arguments of this class.
51
61
 
52
62
  You can deposit all kinds of objects in your power. See the sections below for details.
53
63
 
54
-
55
64
  ### Scope powers (relations)
56
65
 
57
-
58
66
  A typical use case in a Rails application is to restrict access to your ActiveRecord models. For example:
59
67
 
60
68
  - Anonymous visitors may only see public posts
@@ -111,13 +119,10 @@ power.note!(Note.last) # => raises Consul::Powerless unless the given Note is in
111
119
 
112
120
  See our crash course video [Solving bizare authorization requirements with Rails](http://bizarre-authorization.talks.makandra.com/) for many different use cases you can cover with this pattern.
113
121
 
114
-
115
-
116
122
  ### Defining different powers for different actions
117
123
 
118
124
  If you have different access rights for e.g. viewing or updating posts, simply use different powers:
119
125
 
120
-
121
126
  ```rb
122
127
  class Power
123
128
  ...
@@ -139,8 +144,6 @@ end
139
144
 
140
145
  There is also a [shortcut to map different powers to RESTful controller actions](#protect-entry-into-controller-actions).
141
146
 
142
-
143
-
144
147
  ### Boolean powers
145
148
 
146
149
  Boolean powers are useful to control access to stuff that doesn't live in the database:
@@ -164,7 +167,6 @@ power.dashboard? # => true
164
167
  power.dashboard! # => raises Consul::Powerless unless Power#dashboard? returns true
165
168
  ```
166
169
 
167
-
168
170
  ### Powers that give no access at all
169
171
 
170
172
  Note that there is a difference between having access to an empty list of records, and having no access at all.
@@ -194,8 +196,6 @@ power.user?(User.last) # => returns false
194
196
  power.user!(User.last) # => raises Consul::Powerless
195
197
  ```
196
198
 
197
-
198
-
199
199
  ### Powers that only check a given object
200
200
 
201
201
  Sometimes it is not convenient to define powers as a collection or scope (relation).
@@ -203,7 +203,6 @@ Sometimes you only want to store a method that checks whether a given object is
203
203
 
204
204
  To do so, simply define a power that ends in a question mark:
205
205
 
206
-
207
206
  ```rb
208
207
  class Power
209
208
  ...
@@ -223,7 +222,6 @@ power.updatable_post?(Post.last) # return true if the author of the post is @use
223
222
  power.updatable_post!(Post.last) # raises Consul::Powerless unless the author of the post is @user
224
223
  ```
225
224
 
226
-
227
225
  ### Other types of powers
228
226
 
229
227
  A power can return any type of object. For instance, you often want to return an array:
@@ -254,7 +252,6 @@ power.assignable_note_state?('published') # => returns false
254
252
  power.assignable_note_state!('published') # => raises Consul::Powerless
255
253
  ```
256
254
 
257
-
258
255
  ### Defining multiple powers at once
259
256
 
260
257
  You can define multiple powers at once by giving multiple power names:
@@ -270,7 +267,6 @@ class Power
270
267
  end
271
268
  ```
272
269
 
273
-
274
270
  ### Powers that require context (arguments)
275
271
 
276
272
  Sometimes it can be useful to define powers that require context. To do so, just take an argument in your `power` block:
@@ -294,7 +290,6 @@ note = ...
294
290
  Power.current.client_note?(client, note)
295
291
  ```
296
292
 
297
-
298
293
  ### Optimizing record checks for scope powers
299
294
 
300
295
  You can query a scope power for a given record, e.g.
@@ -337,9 +332,7 @@ end
337
332
 
338
333
  This way you do not need to touch the database at all.
339
334
 
340
-
341
- Role-based permissions
342
- ----------------------
335
+ ## Role-based permissions
343
336
 
344
337
  Consul has no built-in support for role-based permissions, but you can easily implement it yourself. Let's say your `User` model has a string column `role` which can be `"author"` or `"admin"`:
345
338
 
@@ -367,9 +360,7 @@ class Power
367
360
  end
368
361
  ```
369
362
 
370
-
371
- Controller integration
372
- ----------------------
363
+ ## Controller integration
373
364
 
374
365
  It is convenient to expose the power for the current request to the rest of the application. Consul will help you with that if you tell it how to instantiate a power for the current request:
375
366
 
@@ -398,7 +389,6 @@ class NotesController < ApplicationController
398
389
  end
399
390
  ```
400
391
 
401
-
402
392
  ### Protect entry into controller actions
403
393
 
404
394
  To make sure a power is given before every action in a controller:
@@ -409,7 +399,7 @@ class NotesController < ApplicationController
409
399
  end
410
400
  ```
411
401
 
412
- You can use `:except` and `:only` options like in before\_actions.
402
+ You can use `:except` and `:only` options like in before_actions.
413
403
 
414
404
  You can also map different powers to different actions:
415
405
 
@@ -441,7 +431,6 @@ class NotesController < ApplicationController
441
431
  end
442
432
  ```
443
433
 
444
-
445
434
  And if your power [requires context](#powers-that-require-context-arguments) (is parametrized), you can give it using the `:context` method:
446
435
 
447
436
  ```rb
@@ -458,8 +447,6 @@ class ClientNotesController < ApplicationController
458
447
  end
459
448
  ```
460
449
 
461
-
462
-
463
450
  ### Auto-mapping a power scope to a controller method
464
451
 
465
452
  It is often convenient to map a power scope to a private controller method:
@@ -486,7 +473,7 @@ class NotesController < ApplicationController
486
473
  power :notes, :as => :note_scope
487
474
 
488
475
  # ...
489
-
476
+
490
477
  def note_scope
491
478
  super.where(trashed: false)
492
479
  end
@@ -494,7 +481,6 @@ class NotesController < ApplicationController
494
481
  end
495
482
  ```
496
483
 
497
-
498
484
  ### Multiple power-mappings for nested resources
499
485
 
500
486
  When using [nested resources](http://guides.rubyonrails.org/routing.html#nested-resources) you probably want two power
@@ -564,7 +550,7 @@ class ApplicationController < ActionController::Base
564
550
  end
565
551
  ```
566
552
 
567
- Note that this check is satisfied by *any* `.power` directive in the controller class or its ancestors, even if that `.power` directive has `:only` or `:except` options that do not apply to the current action.
553
+ Note that this check is satisfied by _any_ `.power` directive in the controller class or its ancestors, even if that `.power` directive has `:only` or `:except` options that do not apply to the current action.
568
554
 
569
555
  Should you want to forego the power check (e.g. to remove authorization checks from an entirely public controller):
570
556
 
@@ -574,9 +560,7 @@ class ApiController < ApplicationController
574
560
  end
575
561
  ```
576
562
 
577
-
578
- Validating assignable values
579
- ----------------------------
563
+ ## Validating assignable values
580
564
 
581
565
  Sometimes a scope is not enough to express what a user can edit. You will often want to give a user write access to a record, but restrict the values she can assign to a given field.
582
566
 
@@ -647,8 +631,7 @@ The `authorize_values_for` macro comes with many useful options and details best
647
631
  assignable_values_for :field, :through => lambda { Power.current }
648
632
  ```
649
633
 
650
- Memoization
651
- -----------
634
+ ## Memoization
652
635
 
653
636
  All power methods are [memoized](https://www.justinweiss.com/articles/4-simple-memoization-patterns-in-ruby-and-one-gem/) for performance reasons. Multiple calls to the same method will only call your block the first time, and return a cached result afterwards:
654
637
 
@@ -665,9 +648,7 @@ If you want to discard all cached results, call `#unmemoize_all`:
665
648
  power.unmemoize_all
666
649
  ```
667
650
 
668
-
669
- Dynamic power access
670
- --------------------
651
+ ## Dynamic power access
671
652
 
672
653
  Consul gives you a way to dynamically access and query powers for a given name, model class or record.
673
654
  A common use case for this are generic helper methods, e.g. a method to display an "edit" link for any given record
@@ -687,30 +668,27 @@ end
687
668
 
688
669
  You can find a full list of available dynamic calls below:
689
670
 
690
- | Dynamic call | Equivalent |
691
- |---------------------------------------------------------|--------------------------------------------|
692
- | `Power.current.send(:notes)` | `Power.current.notes` |
693
- | `Power.current.include_power?(:notes)` | `Power.current.notes?` |
694
- | `Power.current.include_power!(:notes)` | `Power.current.notes!` |
695
- | `Power.current.include_object?(:notes, Note.last)` | `Power.current.note?(Note.last)` |
696
- | `Power.current.include_object!(:notes, Note.last)` | `Power.current.note!(Note.last)` |
697
- | `Power.current.for_model(Note)` | `Power.current.notes` |
698
- | `Power.current.for_model(:updatable, Note)` | `Power.current.updatable_notes` |
699
- | `Power.current.include_model?(Note)` | `Power.current.notes?` |
700
- | `Power.current.include_model?(:updatable, Note)` | `Power.current.updatable_notes?` |
701
- | `Power.current.include_model!(Note)` | `Power.current.notes!` |
702
- | `Power.current.include_model!(:updatable, Note)` | `Power.current.updatable_notes!` |
703
- | `Power.current.include_record?(Note.last)` | `Power.current.note?(Note.last)` |
704
- | `Power.current.include_record?(:updatable, Note.last)` | `Power.current.updatable_note?(Note.last)` |
705
- | `Power.current.include_record!(Note.last)` | `Power.current.note!(Note.last)` |
706
- | `Power.current.include_record!(:updatable, Note.last)` | `Power.current.updatable_note!(Note.last)` |
707
- | `Power.current.name_for_model(Note)` | `:notes` |
708
- | `Power.current.name_for_model(:updatable, Note)` | `:updatable_notes` |
709
-
710
-
711
-
712
- Querying a power that might be nil
713
- ----------------------------------
671
+ | Dynamic call | Equivalent |
672
+ | ------------------------------------------------------ | ------------------------------------------ |
673
+ | `Power.current.send(:notes)` | `Power.current.notes` |
674
+ | `Power.current.include_power?(:notes)` | `Power.current.notes?` |
675
+ | `Power.current.include_power!(:notes)` | `Power.current.notes!` |
676
+ | `Power.current.include_object?(:notes, Note.last)` | `Power.current.note?(Note.last)` |
677
+ | `Power.current.include_object!(:notes, Note.last)` | `Power.current.note!(Note.last)` |
678
+ | `Power.current.for_model(Note)` | `Power.current.notes` |
679
+ | `Power.current.for_model(:updatable, Note)` | `Power.current.updatable_notes` |
680
+ | `Power.current.include_model?(Note)` | `Power.current.notes?` |
681
+ | `Power.current.include_model?(:updatable, Note)` | `Power.current.updatable_notes?` |
682
+ | `Power.current.include_model!(Note)` | `Power.current.notes!` |
683
+ | `Power.current.include_model!(:updatable, Note)` | `Power.current.updatable_notes!` |
684
+ | `Power.current.include_record?(Note.last)` | `Power.current.note?(Note.last)` |
685
+ | `Power.current.include_record?(:updatable, Note.last)` | `Power.current.updatable_note?(Note.last)` |
686
+ | `Power.current.include_record!(Note.last)` | `Power.current.note!(Note.last)` |
687
+ | `Power.current.include_record!(:updatable, Note.last)` | `Power.current.updatable_note!(Note.last)` |
688
+ | `Power.current.name_for_model(Note)` | `:notes` |
689
+ | `Power.current.name_for_model(:updatable, Note)` | `:updatable_notes` |
690
+
691
+ ## Querying a power that might be nil
714
692
 
715
693
  You will often want to access `Power.current` from another model, to e.g. iterate through the list of accessible users:
716
694
 
@@ -760,23 +738,20 @@ end
760
738
 
761
739
  There is a long selection of class methods that behave neutrally in case `Power.current` is `nil`:
762
740
 
763
- | Call | Equivalent |
764
- |----------------------------------------------------------|---------------------------------------------------------------------|
765
- | `Power.for_model(Note)` | `Power.current.present? ? Power.current.notes : Note` |
766
- | `Power.for_model(:updatable, Note)` | `Power.current.present? ? Power.current.updatable_notes : Note` |
767
- | `Power.include_model?(Note)` | `Power.current.present? ? Power.notes? : true` |
768
- | `Power.include_model?(:updatable, Note)` | `Power.current.present? ? Power.updatable_notes? : true` |
769
- | `Power.include_model!(Note)` | `Power.notes! if Power.current.present?` |
770
- | `Power.include_model!(:updatable, Note)` | `Power.updatable_notes! if Power.current.present?` |
771
- | `Power.include_record?(Note.last)` | `Power.current.present? ? Power.note?(Note.last) : true` |
772
- | `Power.include_record?(:updatable, Note.last)` | `Power.current.present? ? Power.updatable_note?(Note.last?) : true` |
773
- | `Power.include_record!(Note.last)` | `Power.note!(Note.last) if Power.current.present?` |
774
- | `Power.include_record!(:updatable, Note.last)` | `Power.updatable_note!(Note.last) if Power.current.present?` |
775
-
776
-
777
-
778
- Testing
779
- -------
741
+ | Call | Equivalent |
742
+ | ---------------------------------------------- | ------------------------------------------------------------------- |
743
+ | `Power.for_model(Note)` | `Power.current.present? ? Power.current.notes : Note` |
744
+ | `Power.for_model(:updatable, Note)` | `Power.current.present? ? Power.current.updatable_notes : Note` |
745
+ | `Power.include_model?(Note)` | `Power.current.present? ? Power.notes? : true` |
746
+ | `Power.include_model?(:updatable, Note)` | `Power.current.present? ? Power.updatable_notes? : true` |
747
+ | `Power.include_model!(Note)` | `Power.notes! if Power.current.present?` |
748
+ | `Power.include_model!(:updatable, Note)` | `Power.updatable_notes! if Power.current.present?` |
749
+ | `Power.include_record?(Note.last)` | `Power.current.present? ? Power.note?(Note.last) : true` |
750
+ | `Power.include_record?(:updatable, Note.last)` | `Power.current.present? ? Power.updatable_note?(Note.last?) : true` |
751
+ | `Power.include_record!(Note.last)` | `Power.note!(Note.last) if Power.current.present?` |
752
+ | `Power.include_record!(:updatable, Note.last)` | `Power.updatable_note!(Note.last) if Power.current.present?` |
753
+
754
+ ## Testing
780
755
 
781
756
  This section Some hints for testing authorization with Consul.
782
757
 
@@ -847,9 +822,7 @@ Power.without_power do
847
822
  end
848
823
  ```
849
824
 
850
-
851
- Installation
852
- ------------
825
+ ## Installation
853
826
 
854
827
  Add the following to your `Gemfile`:
855
828
 
@@ -859,15 +832,13 @@ gem 'consul'
859
832
 
860
833
  Now run `bundle install` to lock the gem into your project.
861
834
 
835
+ ## Development
862
836
 
863
- Development
864
- -----------
865
-
866
- We currently develop using Ruby 2.5.3 (see `.ruby-version`) since that version works for current versions of ActiveRecord that we support. GitHub Actions will test additional Ruby versions (2.3.8, 2.4.5, and 3.0.1).
837
+ We currently develop using Ruby 3.4.1 (see `.ruby-version`) since that version works for current versions of ActiveRecord that we support. GitHub Actions will test additional Ruby versions (2.7.3, 3.2.0).
867
838
 
868
839
  There are tests in `spec`. We only accept PRs with tests. To run tests:
869
840
 
870
- - Install Ruby 2.5.3
841
+ - Install Ruby 3.4.1
871
842
  - run `bundle install`
872
843
  - Put your database credentials into `spec/support/database.yml`. There's a `database.sample.yml` you can use as a template.
873
844
  - There are gem bundles in the project root for each rails version that we support.
@@ -884,8 +855,6 @@ Note that we have configured GitHub Actions to automatically run tests in all su
884
855
 
885
856
  I'm very eager to keep this gem leightweight and on topic. If you're unsure whether a change would make it into the gem, [talk to me beforehand](mailto:henning.koch@makandra.de).
886
857
 
887
-
888
- Credits
889
- -------
858
+ ## Credits
890
859
 
891
860
  Henning Koch from [makandra](http://makandra.com/)
data/consul.gemspec CHANGED
@@ -26,8 +26,8 @@ Gem::Specification.new do |s|
26
26
  s.require_paths = ["lib"]
27
27
 
28
28
  s.add_dependency('memoized', '>=1.0.2')
29
- s.add_dependency('activerecord', '>= 3.2')
30
- s.add_dependency('activesupport', '>= 3.2')
31
- s.add_dependency('railties', '>= 3.2')
29
+ s.add_dependency('activerecord', '>= 6.0')
30
+ s.add_dependency('activesupport', '>= 6.0')
31
+ s.add_dependency('railties', '>= 6.0')
32
32
  s.add_dependency('edge_rider', '>= 0.3.0')
33
33
  end
@@ -14,4 +14,6 @@ module Consul
14
14
  end
15
15
  end
16
16
 
17
- ActiveRecord::Base.send(:extend, Consul::ActiveRecord)
17
+ ActiveSupport.on_load(:active_record) do
18
+ extend(Consul::ActiveRecord)
19
+ end
data/lib/consul/util.rb CHANGED
@@ -3,11 +3,7 @@ module Consul
3
3
  extend self
4
4
 
5
5
  def scope_selects_all_records?(scope)
6
- if Rails.version.to_i < 3
7
- scope = scope.scoped({})
8
- else
9
- scope = scope.scoped
10
- end
6
+ scope = scope.scoped
11
7
  scope_sql = scope.to_sql
12
8
  quoted_table_name = Regexp.quote(scope.connection.quote_table_name(scope.table_name))
13
9
  all_sql_pattern = /\ASELECT (#{quoted_table_name}\.)?\* FROM #{quoted_table_name}\z/
@@ -23,26 +19,17 @@ module Consul
23
19
  end
24
20
 
25
21
  def define_scope(klass, name, lambda)
26
- if Rails.version.to_i < 4 # Rails 2/3
27
- scope_definition = Rails.version.to_i < 3 ? :named_scope : :scope
28
- klass.send scope_definition, name, lambda
29
- else
30
- klass.send :scope, name, lambda { |*args|
31
- options = lambda.call(*args)
32
- klass.scoped(options.slice *EdgeRider::Scoped::VALID_FIND_OPTIONS)
33
- }
34
- end
22
+ klass.send :scope, name, lambda { |*args|
23
+ options = lambda.call(*args)
24
+ klass.scoped(options.slice *EdgeRider::Scoped::VALID_FIND_OPTIONS)
25
+ }
35
26
  end
36
27
 
37
28
  # This method does not support dynamic default scopes via lambdas
38
29
  # (as does #define_scope), because it is currently not required.
39
30
  def define_default_scope(klass, conditions)
40
- if Rails.version.to_i < 4 # Rails 2/3
41
- klass.send :default_scope, conditions
42
- else
43
- klass.send :default_scope do
44
- klass.scoped(conditions)
45
- end
31
+ klass.send :default_scope do
32
+ klass.scoped(conditions)
46
33
  end
47
34
  end
48
35
 
@@ -58,33 +45,19 @@ module Consul
58
45
  end
59
46
 
60
47
  def skip_before_action(controller_class, name, options)
61
- if Rails.version.to_i < 4
62
- controller_class.skip_before_filter name, options
63
- elsif Rails.version.to_i < 5
64
- controller_class.skip_before_action name, options
65
- else
66
- # Every `power` in a controller will skip the power check filter. After the 1st time, Rails 5+ will raise
67
- # an error because there is no `unchecked_power` action to skip any more.
68
- # To avoid this, we add the following extra option. Note that it must not be added in Rails 4 to avoid errors.
69
- # See http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-skip_callback
70
- controller_class.skip_before_action name, { :raise => false }.merge!(options)
71
- end
48
+ # Every `power` in a controller will skip the power check filter. After the 1st time, Rails will raise
49
+ # an error because there is no `unchecked_power` action to skip any more.
50
+ # To avoid this, we add the following extra option.
51
+ # See http://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-skip_callback
52
+ controller_class.skip_before_action name, { :raise => false }.merge!(options)
72
53
  end
73
54
 
74
55
  def before_action(controller_class, *args, &block)
75
- if Rails.version.to_i < 4
76
- controller_class.before_filter *args, &block
77
- else
78
- controller_class.before_action *args, &block
79
- end
56
+ controller_class.before_action *args, &block
80
57
  end
81
58
 
82
59
  def around_action(controller_class, *args, &block)
83
- if Rails.version.to_i < 4
84
- controller_class.around_filter *args, &block
85
- else
86
- controller_class.around_action *args, &block
87
- end
60
+ controller_class.around_action *args, &block
88
61
  end
89
62
 
90
63
  end
@@ -1,3 +1,3 @@
1
1
  module Consul
2
- VERSION = '1.3.1'
2
+ VERSION = '2.0.0'
3
3
  end