active_manageable 0.1.2 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +12 -0
- data/Gemfile.lock +1 -1
- data/README.md +81 -11
- data/lib/active_manageable/authorization/cancancan.rb +10 -12
- data/lib/active_manageable/authorization/pundit.rb +10 -12
- data/lib/active_manageable/base.rb +14 -3
- data/lib/active_manageable/configuration.rb +16 -7
- data/lib/active_manageable/methods/auxiliary/includes.rb +28 -30
- data/lib/active_manageable/methods/auxiliary/model_attributes.rb +15 -17
- data/lib/active_manageable/methods/auxiliary/order.rb +12 -14
- data/lib/active_manageable/methods/auxiliary/scopes.rb +35 -28
- data/lib/active_manageable/methods/auxiliary/select.rb +11 -13
- data/lib/active_manageable/methods/auxiliary/unique_search.rb +19 -19
- data/lib/active_manageable/methods/create.rb +20 -5
- data/lib/active_manageable/methods/destroy.rb +22 -7
- data/lib/active_manageable/methods/edit.rb +17 -9
- data/lib/active_manageable/methods/index.rb +28 -26
- data/lib/active_manageable/methods/new.rb +14 -6
- data/lib/active_manageable/methods/show.rb +17 -9
- data/lib/active_manageable/methods/update.rb +28 -7
- data/lib/active_manageable/pagination/kaminari.rb +29 -9
- data/lib/active_manageable/search/ransack.rb +15 -17
- data/lib/active_manageable/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 33e6916eea9e70cfa5c04813328b8e1cb21e93f3f2638705b2ec0b37748de51c
|
4
|
+
data.tar.gz: 37122950ad83b210bd043ce2fc556032451df60deef18dc4f58cead9917f1f1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2afeaad9032f497b31208e0e4c8b21e209b40d81346dc1468a3eefdb251e1d6c5c01f6759d58e2cab99782116920845077fd62bcb90a54e20ac7c322c556647
|
7
|
+
data.tar.gz: 608affa3ab36c003c03c0af6f27d09b404cfd6e8b987bd6ec57b3605b7f93910b95409073afda386f1e4fb33998cb07bdcc1428ddcf23ae3bac5eb2e2b0eefb7
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,17 @@
|
|
1
1
|
# Change Log
|
2
2
|
|
3
|
+
## 0.2.0 - 2022-09-27
|
4
|
+
|
5
|
+
* Allow the configuration library options to accept a module
|
6
|
+
* Add `action_scope` method that can be overridden in order to retrieve and maintain records using a scope
|
7
|
+
* Rename `scoped_class` method to `authorization_scope`
|
8
|
+
* Move instance method definitions out of the ActiveSupport::Concern included block so that they can be overridden
|
9
|
+
* Split action methods into smaller overridable methods
|
10
|
+
* Add a yield to each of the action methods
|
11
|
+
* Perform yield and object create, update & destroy within a transaction
|
12
|
+
* Add public instance methods to return the default options
|
13
|
+
* When using the Kaminari library provide the ability to use the `without_count` mode to create a paginatable collection without counting the total number of records; either via the index method options or a class option or configuration option
|
14
|
+
|
3
15
|
## 0.1.2 - 2022-08-25
|
4
16
|
|
5
17
|
* Upgrade gems including activerecord, actionpack, actionview, nokogiri & rack to resolve security advisory alerts
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -49,7 +49,7 @@ def index
|
|
49
49
|
end
|
50
50
|
```
|
51
51
|
|
52
|
-
The manager classes provide standard implementations of the seven core CRUD methods. These can be overwritten to perform custom business logic and the classes can also be extended to include the business logic for additional actions, both making use of the internal ActiveManageable methods and variables described in the [Adding Bespoke Methods](#adding-bespoke-methods) section.
|
52
|
+
The manager classes provide standard implementations of the seven core CRUD methods. These can be extended or overwritten to perform custom business logic and the classes can also be extended to include the business logic for additional actions, both making use of the internal ActiveManageable methods and variables described in the [Adding Bespoke Methods](#adding-bespoke-methods) section.
|
53
53
|
|
54
54
|
With an Activity model in a CRM application to manage meetings & tasks, a complete action may be required. This could be implemented as follows:
|
55
55
|
|
@@ -110,6 +110,7 @@ gem install active_manageable
|
|
110
110
|
- [Default Scopes](#default-scopes)
|
111
111
|
- [Unique Search](#unique-search)
|
112
112
|
- [Default Page Size](#default-page-size)
|
113
|
+
- [Paginate Without Count](#paginate-without-count)
|
113
114
|
- [Current Method](#current-method)
|
114
115
|
- [Index Method](#index-method)
|
115
116
|
- [Authorization Scope](#index-authorization-scope)
|
@@ -131,6 +132,8 @@ gem install active_manageable
|
|
131
132
|
- [Includes Option](#update-includes-option)
|
132
133
|
- [Destroy Method](#destroy-method)
|
133
134
|
- [Includes Option](#destroy-includes-option)
|
135
|
+
- [Extending the CRUD Methods](#extending-the-crud-methods)
|
136
|
+
- [Build and Retrieve Scoped Records](#build-and-retrieve-scoped-records)
|
134
137
|
- [Attribute Value Parsing](#attribute-value-parsing)
|
135
138
|
- [Date and DateTime Attribute Values](#date-and-datetime-attribute-values)
|
136
139
|
- [Numeric Attribute Values](#numeric-attribute-values)
|
@@ -143,7 +146,7 @@ gem install active_manageable
|
|
143
146
|
|
144
147
|
## Configuration
|
145
148
|
|
146
|
-
Create an initializer to configure the optional authorization, search and pagination libraries to use.
|
149
|
+
Create an initializer to configure the optional in-built authorization, search and pagination libraries to use.
|
147
150
|
|
148
151
|
```ruby
|
149
152
|
ActiveManageable.config do |config|
|
@@ -153,6 +156,8 @@ ActiveManageable.config do |config|
|
|
153
156
|
end
|
154
157
|
```
|
155
158
|
|
159
|
+
These library configuration options can also be set to a module in order to use a custom authorization, search or pagination implementation.
|
160
|
+
|
156
161
|
When eager loading associations the `includes` method is used by default but this can be changed via a configuration option that accepts `:includes`, `:preload` or `:eager_load`
|
157
162
|
|
158
163
|
```ruby
|
@@ -388,6 +393,31 @@ class AlbumManager < ActiveManageable::Base
|
|
388
393
|
end
|
389
394
|
```
|
390
395
|
|
396
|
+
### Paginate Without Count
|
397
|
+
|
398
|
+
When using the [Kaminari](https://github.com/kaminari/kaminari) pagination library, the `paginate_without_count` method will result in the index method using the Kaminari `without_count` mode to create a paginatable collection without counting the total number of records.
|
399
|
+
|
400
|
+
```ruby
|
401
|
+
class AlbumManager < ActiveManageable::Base
|
402
|
+
manageable :index
|
403
|
+
paginate_without_count
|
404
|
+
end
|
405
|
+
```
|
406
|
+
|
407
|
+
It is also possible to control whether to use the `without_count` mode globally by setting the `paginate_without_count` configuration option.
|
408
|
+
|
409
|
+
```ruby
|
410
|
+
ActiveManageable.config do |config|
|
411
|
+
config.paginate_without_count = true
|
412
|
+
end
|
413
|
+
```
|
414
|
+
|
415
|
+
And it is also possible to control whether to use the `without_count` mode for an individual index method call by including the `:without_count` key within the `options` argument `:page` hash.
|
416
|
+
|
417
|
+
```ruby
|
418
|
+
manager.index(options: {page: {number: 2, size: 10, without_count: true}})
|
419
|
+
```
|
420
|
+
|
391
421
|
### Current Method
|
392
422
|
|
393
423
|
ActiveManageable includes a `current_method` attribute which returns the name of the method being executed as a symbol, which can potentially be used within methods in conjunction with a lambda for the default methods described above. Additionally, the method argument `options` and `attributes` are also accessible as attributes.
|
@@ -411,7 +441,7 @@ end
|
|
411
441
|
|
412
442
|
## Index Method
|
413
443
|
|
414
|
-
The `index` method has an optional `options` keyword argument. The `options` hash can contain `:search`, `:order`, `:scopes`, `:page`, `:includes` and `:select` keys. The method performs authorization for the current user, method and model class using the configuration library; retrieves
|
444
|
+
The `index` method has an optional `options` keyword argument. The `options` hash can contain `:search`, `:order`, `:scopes`, `:page`, `:includes` and `:select` keys. The method performs authorization for the current user, method and model class using the configuration library; invokes a block (if provided); retrieves records using the various options described below; and returns the records which are also accessible via the `collection` attribute.
|
415
445
|
|
416
446
|
```ruby
|
417
447
|
manager.index
|
@@ -490,7 +520,7 @@ If the class `has_unique_search` method has been used then this will be evaluate
|
|
490
520
|
|
491
521
|
## Show Method
|
492
522
|
|
493
|
-
The `show` method has `id` and optional `options` keyword arguments. The `options` hash can contain `:includes` and `:select` keys. The method retrieves a record; performs authorization for the current user, method and record using the configuration library; and returns the record which is also accessible via the `object` attribute.
|
523
|
+
The `show` method has `id` and optional `options` keyword arguments. The `options` hash can contain `:includes` and `:select` keys. The method invokes a block (if provided); retrieves a record; performs authorization for the current user, method and record using the configuration library; and returns the record which is also accessible via the `object` attribute.
|
494
524
|
|
495
525
|
```ruby
|
496
526
|
manager.show(id: 1)
|
@@ -520,7 +550,7 @@ manager.show(id: 1, options: {select: [:id, :name, :artist_id, :released_at]})
|
|
520
550
|
|
521
551
|
## New Method
|
522
552
|
|
523
|
-
The `new` method has an optional `attributes` keyword argument. The `attributes` argument is for an `ActionController::Parameters` or hash of attribute names and values to use when building the record. The method builds a record; performs authorization for the current user, method and record using the configuration library; and returns the record which is also accessible via the `object` attribute.
|
553
|
+
The `new` method has an optional `attributes` keyword argument. The `attributes` argument is for an `ActionController::Parameters` or hash of attribute names and values to use when building the record. The method builds a record; performs authorization for the current user, method and record using the configuration library; invokes a block (if provided); and returns the record which is also accessible via the `object` attribute.
|
524
554
|
|
525
555
|
```ruby
|
526
556
|
manager.new
|
@@ -534,7 +564,7 @@ manager.new(attributes: {genre: "electronic", published_at: Date.current})
|
|
534
564
|
|
535
565
|
## Create Method
|
536
566
|
|
537
|
-
The `create` method has an `attributes` keyword argument. The `attributes` argument is for an `ActionController::Parameters` or hash of attribute names and values to use when building the record. The method builds a record; performs authorization for the current user, method and record using the configuration library; attempts to save the record and returns the save result. The record is also accessible via the `object` attribute.
|
567
|
+
The `create` method has an `attributes` keyword argument. The `attributes` argument is for an `ActionController::Parameters` or hash of attribute names and values to use when building the record. The method builds a record; performs authorization for the current user, method and record using the configuration library; invokes a block (if provided) and attempts to save the record within a transaction; and returns the save result. The record is also accessible via the `object` attribute.
|
538
568
|
|
539
569
|
```ruby
|
540
570
|
manager.create(attributes: {name: "Substance", genre: "electronic", published_at: Date.current})
|
@@ -544,7 +574,7 @@ The `attributes` argument values are combined with the class default values and
|
|
544
574
|
|
545
575
|
## Edit Method
|
546
576
|
|
547
|
-
The `edit` method has `id` and optional `options` keyword arguments. The `options` hash can contain `:includes` and `:select` keys. The method retrieves a record; performs authorization for the current user, method and record using the configuration library; and returns the record which is also accessible via the `object` attribute.
|
577
|
+
The `edit` method has `id` and optional `options` keyword arguments. The `options` hash can contain `:includes` and `:select` keys. The method invokes a block (if provided); retrieves a record; performs authorization for the current user, method and record using the configuration library; and returns the record which is also accessible via the `object` attribute.
|
548
578
|
|
549
579
|
```ruby
|
550
580
|
manager.edit(id: 1)
|
@@ -566,7 +596,7 @@ manager.edit(id: 1, options: {includes: {associations: :songs, loading_method: :
|
|
566
596
|
|
567
597
|
## Update Method
|
568
598
|
|
569
|
-
The `update` method has `id`, `attributes` and optional `options` keyword arguments. The `attributes` argument is for an `ActionController::Parameters` or hash of attribute names and values to use when updating the record. The `options` hash can contain an `:includes` key. The method retrieves a record; performs authorization for the current user, method and record using the configuration library;
|
599
|
+
The `update` method has `id`, `attributes` and optional `options` keyword arguments. The `attributes` argument is for an `ActionController::Parameters` or hash of attribute names and values to use when updating the record. The `options` hash can contain an `:includes` key. The method retrieves a record; performs authorization for the current user, method and record using the configuration library; assigns the attributes; invokes a block (if provided) and attempts to save the record within a transaction; and returns the save result. The record is also accessible via the `object` attribute.
|
570
600
|
|
571
601
|
```ruby
|
572
602
|
manager.update(id: 1, attributes: {genre: "electronic", published_at: Date.current})
|
@@ -588,7 +618,7 @@ manager.update(id: 1, attributes: {published_at: Date.current}, options: {includ
|
|
588
618
|
|
589
619
|
## Destroy Method
|
590
620
|
|
591
|
-
The `destroy` method has `id` and optional `options` keyword arguments. The `options` hash can contain an `:includes` key. The method retrieves a record; performs authorization for the current user, method and record using the configuration library; attempts to destroy the record and returns the destroy result. The record is accessible via the `object` attribute.
|
621
|
+
The `destroy` method has `id` and optional `options` keyword arguments. The `options` hash can contain an `:includes` key. The method retrieves a record; performs authorization for the current user, method and record using the configuration library; invokes a block (if provided) and attempts to destroy the record within a transaction; and returns the destroy result. The record is accessible via the `object` attribute.
|
592
622
|
|
593
623
|
```ruby
|
594
624
|
manager.destroy(id: 1)
|
@@ -608,6 +638,37 @@ The `:includes` key can also be used to vary the method used to eager load assoc
|
|
608
638
|
manager.destroy(id: 1, options: {includes: {associations: :songs, loading_method: :preload}})
|
609
639
|
```
|
610
640
|
|
641
|
+
## Extending the CRUD Methods
|
642
|
+
|
643
|
+
Each of the seven core CRUD methods include a `yield` so it is possible to extend the methods by passing a block.
|
644
|
+
|
645
|
+
```ruby
|
646
|
+
def create(attributes:)
|
647
|
+
super do
|
648
|
+
@target.description = "change the object before it is created using a block"
|
649
|
+
end
|
650
|
+
end
|
651
|
+
```
|
652
|
+
|
653
|
+
The logic within each of the methods has also been split into subsidiary methods so it is possible to extend or override these methods.
|
654
|
+
|
655
|
+
```ruby
|
656
|
+
def create_object
|
657
|
+
@target.description = "change the object before it is created via an override"
|
658
|
+
super
|
659
|
+
end
|
660
|
+
```
|
661
|
+
|
662
|
+
## Build and Retrieve Scoped Records
|
663
|
+
|
664
|
+
Each of the seven core CRUD methods build and retrieve records using the `action_scope` method which by default returns the model class. In order to build or retrieve records using a scope it is possible to override this method.
|
665
|
+
|
666
|
+
```ruby
|
667
|
+
def action_scope
|
668
|
+
current_user.albums
|
669
|
+
end
|
670
|
+
```
|
671
|
+
|
611
672
|
## Attribute Value Parsing
|
612
673
|
|
613
674
|
### Date and DateTime Attribute Values
|
@@ -693,7 +754,7 @@ ActiveManageable includes the following attributes:
|
|
693
754
|
|
694
755
|
## Adding Bespoke Methods
|
695
756
|
|
696
|
-
The manager classes provide standard implementations of the seven core CRUD methods. These can be overwritten to perform custom business logic and the classes can also be extended to include the business logic for additional actions, both making use of the internal ActiveManageable methods and variables.
|
757
|
+
The manager classes provide standard implementations of the seven core CRUD methods. These can be extended or overwritten to perform custom business logic and the classes can also be extended to include the business logic for additional actions, both making use of the internal ActiveManageable methods and variables.
|
697
758
|
|
698
759
|
```ruby
|
699
760
|
def complete(id:)
|
@@ -737,7 +798,16 @@ After making changes:
|
|
737
798
|
4. run `bundle exec appraisal rspec` to run the tests against different versions of activerecord & activesupport
|
738
799
|
5. run `bundle exec rubocop` to check the style of files
|
739
800
|
|
740
|
-
To install this gem onto your local machine, run `bundle exec rake install`.
|
801
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
802
|
+
|
803
|
+
To release a new version:
|
804
|
+
|
805
|
+
1. update the version number in `version.rb`
|
806
|
+
2. update the change log in `CHANGELOG.md`
|
807
|
+
3. run `bundle` to update the `Gemfile.lock` version
|
808
|
+
4. commit the changes
|
809
|
+
5. run `bundle exec rake release` to create & push a git tag for the version and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
810
|
+
6. create a new release for the version on GitHub
|
741
811
|
|
742
812
|
## Contributing
|
743
813
|
|
@@ -7,21 +7,19 @@ module ActiveManageable
|
|
7
7
|
module CanCanCan
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
-
|
11
|
-
private
|
10
|
+
private
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def authorize(record:, action: nil)
|
13
|
+
action ||= @current_method
|
14
|
+
current_ability.authorize!(action, record)
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def authorization_scope
|
18
|
+
model_class.accessible_by(current_ability)
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
21
|
+
def current_ability
|
22
|
+
::Ability.new(current_user)
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -7,21 +7,19 @@ module ActiveManageable
|
|
7
7
|
module Pundit
|
8
8
|
extend ActiveSupport::Concern
|
9
9
|
|
10
|
-
|
11
|
-
private
|
10
|
+
private
|
12
11
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
12
|
+
def authorize(record:, action: nil)
|
13
|
+
action ||= authorize_action
|
14
|
+
::Pundit.authorize(current_user, record, action)
|
15
|
+
end
|
17
16
|
|
18
|
-
|
19
|
-
|
20
|
-
|
17
|
+
def authorization_scope
|
18
|
+
::Pundit.policy_scope(current_user, model_class)
|
19
|
+
end
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
end
|
21
|
+
def authorize_action
|
22
|
+
"#{@current_method}?".to_sym
|
25
23
|
end
|
26
24
|
end
|
27
25
|
end
|
@@ -4,12 +4,13 @@ module ActiveManageable
|
|
4
4
|
class_attribute :defaults, instance_writer: false, instance_predicate: false
|
5
5
|
class_attribute :module_initialize_state_methods, instance_writer: false, instance_predicate: false
|
6
6
|
|
7
|
-
|
7
|
+
attr_accessor :target
|
8
|
+
attr_reader :current_method, :attributes, :options
|
8
9
|
|
9
10
|
# target provides a common variable to use within the CRUD, auxiliary & library methods
|
10
11
|
# whereas the object & collection methods provide less ambiguous external access
|
11
|
-
|
12
|
-
|
12
|
+
alias_attribute :object, :target
|
13
|
+
alias_attribute :collection, :target
|
13
14
|
|
14
15
|
class << self
|
15
16
|
# Ruby method called when a child class inherits from a parent class
|
@@ -58,6 +59,8 @@ module ActiveManageable
|
|
58
59
|
include ActiveManageable::Authorization::Pundit
|
59
60
|
when :cancancan
|
60
61
|
include ActiveManageable::Authorization::CanCanCan
|
62
|
+
when Module
|
63
|
+
include ActiveManageable.configuration.authorization_library
|
61
64
|
end
|
62
65
|
end
|
63
66
|
|
@@ -65,6 +68,8 @@ module ActiveManageable
|
|
65
68
|
case ActiveManageable.configuration.search_library
|
66
69
|
when :ransack
|
67
70
|
include ActiveManageable::Search::Ransack
|
71
|
+
when Module
|
72
|
+
include ActiveManageable.configuration.search_library
|
68
73
|
end
|
69
74
|
end
|
70
75
|
|
@@ -72,6 +77,8 @@ module ActiveManageable
|
|
72
77
|
case ActiveManageable.configuration.pagination_library
|
73
78
|
when :kaminari
|
74
79
|
include ActiveManageable::Pagination::Kaminari
|
80
|
+
when Module
|
81
|
+
include ActiveManageable.configuration.pagination_library
|
75
82
|
end
|
76
83
|
end
|
77
84
|
|
@@ -109,6 +116,10 @@ module ActiveManageable
|
|
109
116
|
|
110
117
|
private
|
111
118
|
|
119
|
+
def action_scope
|
120
|
+
model_class
|
121
|
+
end
|
122
|
+
|
112
123
|
def initialize_state(attributes: {}, options: {})
|
113
124
|
@target = nil
|
114
125
|
@current_method = calling_method
|
@@ -6,31 +6,32 @@ module ActiveManageable
|
|
6
6
|
|
7
7
|
class Configuration
|
8
8
|
attr_reader :authorization_library, :search_library, :pagination_library, :default_loading_method
|
9
|
-
attr_accessor :subclass_suffix
|
9
|
+
attr_accessor :subclass_suffix, :paginate_without_count
|
10
10
|
|
11
11
|
def initialize
|
12
12
|
@default_loading_method = :includes
|
13
13
|
@subclass_suffix = "Manager"
|
14
|
+
@paginate_without_count = false
|
14
15
|
end
|
15
16
|
|
16
17
|
def authorization_library=(authorization_library)
|
17
18
|
raise ArgumentError.new("Invalid authorization library") unless authorization_library_valid?(authorization_library)
|
18
|
-
@authorization_library = authorization_library
|
19
|
+
@authorization_library = authorization_library
|
19
20
|
end
|
20
21
|
|
21
22
|
def search_library=(search_library)
|
22
23
|
raise ArgumentError.new("Invalid search library") unless search_library_valid?(search_library)
|
23
|
-
@search_library = search_library
|
24
|
+
@search_library = search_library
|
24
25
|
end
|
25
26
|
|
26
27
|
def pagination_library=(pagination_library)
|
27
28
|
raise ArgumentError.new("Invalid pagination library") unless pagination_library_valid?(pagination_library)
|
28
|
-
@pagination_library = pagination_library
|
29
|
+
@pagination_library = pagination_library
|
29
30
|
end
|
30
31
|
|
31
32
|
def default_loading_method=(default_loading_method)
|
32
33
|
raise ArgumentError.new("Invalid method for eager loading") unless default_loading_method_valid?(default_loading_method)
|
33
|
-
@default_loading_method = default_loading_method
|
34
|
+
@default_loading_method = default_loading_method
|
34
35
|
end
|
35
36
|
|
36
37
|
private
|
@@ -48,11 +49,19 @@ module ActiveManageable
|
|
48
49
|
end
|
49
50
|
|
50
51
|
def default_loading_method_valid?(default_loading_method)
|
51
|
-
|
52
|
+
symbol_option_valid?(LOADING_METHODS, default_loading_method)
|
52
53
|
end
|
53
54
|
|
54
55
|
def option_valid?(options, option)
|
55
|
-
|
56
|
+
symbol_option_valid?(options, option) || module_option_valid?(option)
|
57
|
+
end
|
58
|
+
|
59
|
+
def symbol_option_valid?(options, option)
|
60
|
+
option.is_a?(Symbol) && options.include?(option.to_s.to_sym)
|
61
|
+
end
|
62
|
+
|
63
|
+
def module_option_valid?(option)
|
64
|
+
option.is_a?(Module)
|
56
65
|
end
|
57
66
|
end
|
58
67
|
end
|
@@ -33,7 +33,7 @@ module ActiveManageable
|
|
33
33
|
# the associations and options we cannot use the array extract_options! method
|
34
34
|
# as this removes the last element in the array if it's a hash.
|
35
35
|
#
|
36
|
-
# For example
|
36
|
+
# For example:-
|
37
37
|
# default_includes songs: :artist, loading_method: :preload, methods: :index
|
38
38
|
# results in an argument value of :-
|
39
39
|
# [{:songs=>:artist, :loading_method=>:preload, :methods=>:index}]
|
@@ -58,38 +58,36 @@ module ActiveManageable
|
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
61
|
-
|
62
|
-
|
61
|
+
def default_includes(method: @current_method)
|
62
|
+
includes = defaults[:includes] || {}
|
63
|
+
associations = includes.dig(method.try(:to_sym), :associations) || includes.dig(:all, :associations)
|
64
|
+
associations.is_a?(Proc) ? instance_exec(&associations) : associations
|
65
|
+
end
|
63
66
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
# or configuration default loading_method.
|
70
|
-
def includes(opts)
|
71
|
-
unless opts.is_a?(Hash) && opts.key?(:associations)
|
72
|
-
opts = {associations: opts}
|
73
|
-
end
|
74
|
-
associations = opts[:associations] || get_default_includes_associations
|
75
|
-
if associations.present?
|
76
|
-
loading_method = opts[:loading_method] || get_default_includes_loading_method
|
77
|
-
@target = @target.send(loading_method, associations)
|
78
|
-
else
|
79
|
-
@target
|
80
|
-
end
|
81
|
-
end
|
67
|
+
def default_loading_method(method: @current_method)
|
68
|
+
includes = defaults[:includes] || {}
|
69
|
+
loading_method = includes.dig(method.try(:to_sym), :loading_method) || includes.dig(:all, :loading_method)
|
70
|
+
loading_method || ActiveManageable.configuration.default_loading_method
|
71
|
+
end
|
82
72
|
|
83
|
-
|
84
|
-
includes = defaults[:includes] || {}
|
85
|
-
associations = includes.dig(@current_method, :associations) || includes.dig(:all, :associations)
|
86
|
-
associations.is_a?(Proc) ? instance_exec(&associations) : associations
|
87
|
-
end
|
73
|
+
private
|
88
74
|
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
75
|
+
# Accepts either an array/hash of associations
|
76
|
+
# or a hash with associations and loading_method keys
|
77
|
+
# so it's possible to specify loading_method on a per request basis.
|
78
|
+
# Uses associations and loading_method from opts
|
79
|
+
# or defaults for the method or defaults for all methods
|
80
|
+
# or configuration default loading_method.
|
81
|
+
def includes(opts)
|
82
|
+
unless opts.is_a?(Hash) && opts.key?(:associations)
|
83
|
+
opts = {associations: opts}
|
84
|
+
end
|
85
|
+
associations = opts[:associations] || default_includes
|
86
|
+
if associations.present?
|
87
|
+
loading_method = opts[:loading_method] || default_loading_method
|
88
|
+
@target = @target.send(loading_method, associations)
|
89
|
+
else
|
90
|
+
@target
|
93
91
|
end
|
94
92
|
end
|
95
93
|
end
|
@@ -33,25 +33,23 @@ module ActiveManageable
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
|
37
|
-
|
36
|
+
# Returns the default attribute values for the method
|
37
|
+
# from the class attribute that can contain a hash of attribute values
|
38
|
+
# or a lambda/proc to execute to return attribute values
|
39
|
+
def default_attribute_values(method: @current_method)
|
40
|
+
default_attributes = defaults[:attributes] || {}
|
41
|
+
attributes = default_attributes[method.try(:to_sym)] || default_attributes[:all] || {}
|
42
|
+
attributes = (instance_exec(&attributes) || {}) if attributes.is_a?(Proc)
|
43
|
+
attributes.with_indifferent_access
|
44
|
+
end
|
38
45
|
|
39
|
-
|
40
|
-
# consisting of a merge of the method attributes argument
|
41
|
-
# and class defaults with the method argument taking precedence
|
42
|
-
def attribute_values
|
43
|
-
@attributes.is_a?(Hash) ? @attributes.reverse_merge(get_default_attribute_values) : @attributes
|
44
|
-
end
|
46
|
+
private
|
45
47
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
attributes = default_attributes[@current_method] || default_attributes[:all] || {}
|
52
|
-
attributes = (instance_exec(&attributes) || {}) if attributes.is_a?(Proc)
|
53
|
-
attributes.with_indifferent_access
|
54
|
-
end
|
48
|
+
# Returns attribute values to use in the new and create methods
|
49
|
+
# consisting of a merge of the method attributes argument
|
50
|
+
# and class defaults with the method argument taking precedence
|
51
|
+
def attribute_values
|
52
|
+
@attributes.is_a?(Hash) ? @attributes.reverse_merge(default_attribute_values) : @attributes
|
55
53
|
end
|
56
54
|
end
|
57
55
|
end
|
@@ -19,23 +19,21 @@ module ActiveManageable
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
22
|
+
# Returns the default order attributes from the class attribute
|
23
|
+
# that can contain an array of attribute names or name & direction strings
|
24
|
+
# or a lambda/proc to execute to return an array of attribute names
|
25
|
+
def default_order
|
26
|
+
defaults[:order].is_a?(Proc) ? instance_exec(&defaults[:order]) : defaults[:order]
|
27
|
+
end
|
24
28
|
|
25
|
-
|
26
|
-
@target = @target.order(get_order_attributes(attributes))
|
27
|
-
end
|
29
|
+
private
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
|
31
|
+
def order(attributes)
|
32
|
+
@target = @target.order(order_attributes(attributes))
|
33
|
+
end
|
32
34
|
|
33
|
-
|
34
|
-
|
35
|
-
# or a lambda/proc to execute to return an array of attribute names
|
36
|
-
def get_default_order_attributes
|
37
|
-
defaults[:order].is_a?(Proc) ? instance_exec(&defaults[:order]) : defaults[:order]
|
38
|
-
end
|
35
|
+
def order_attributes(attributes)
|
36
|
+
attributes || default_order
|
39
37
|
end
|
40
38
|
end
|
41
39
|
end
|
@@ -20,37 +20,44 @@ module ActiveManageable
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
-
|
24
|
-
|
23
|
+
# Returns the default scopes in a hash of hashes with the key containing the scope name
|
24
|
+
# and value containing an array of scope arguments.
|
25
|
+
#
|
26
|
+
# For example:-
|
27
|
+
# {rock: [], electronic: [], released_in_year: ["1980"]}
|
28
|
+
def default_scopes
|
29
|
+
get_scopes
|
30
|
+
end
|
25
31
|
|
26
|
-
|
27
|
-
get_scopes(scopes).each { |name, args| @target = @target.send(name, *args) }
|
28
|
-
@target
|
29
|
-
end
|
32
|
+
private
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
# and value containing an array of scope arguments.
|
36
|
-
def get_scopes(scopes = nil)
|
37
|
-
scopes ||= defaults[:scopes]
|
34
|
+
def scopes(scopes)
|
35
|
+
get_scopes(scopes).each { |name, args| @target = @target.send(name, *args) }
|
36
|
+
@target
|
37
|
+
end
|
38
38
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
39
|
+
# Accepts a symbol or string scope name, hash containing scope name and argument,
|
40
|
+
# lambda/proc to execute to return scope(s) or an array of those types
|
41
|
+
# and when the argument is blank it uses the class default scopes.
|
42
|
+
# Converts the scopes to a hash of hashes with the key containing the scope name
|
43
|
+
# and value containing an array of scope arguments.
|
44
|
+
def get_scopes(scopes = nil)
|
45
|
+
scopes ||= defaults[:scopes]
|
46
|
+
|
47
|
+
Array.wrap(scopes).map do |scope|
|
48
|
+
case scope
|
49
|
+
when Symbol, String
|
50
|
+
{scope => []}
|
51
|
+
when Hash
|
52
|
+
# ensure values are an array so they can be passed to the scope using splat operator
|
53
|
+
scope.transform_values! { |v| Array.wrap(v) }
|
54
|
+
when Proc
|
55
|
+
# if the class default contains a lambda/proc that returns nil
|
56
|
+
# don't call get_scopes as we don't want to end up in an infinite loop
|
57
|
+
p_scopes = instance_exec(&scope)
|
58
|
+
get_scopes(p_scopes) if p_scopes.present?
|
59
|
+
end
|
60
|
+
end.compact.reduce({}, :merge)
|
54
61
|
end
|
55
62
|
end
|
56
63
|
end
|
@@ -24,21 +24,19 @@ module ActiveManageable
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
-
|
28
|
-
|
27
|
+
# Returns the default select attributes for the method
|
28
|
+
# from the class attribute that can contain an array of attribute names
|
29
|
+
# or a lambdas/procs to execute to return an array of attribute names
|
30
|
+
def default_select(method: @current_method)
|
31
|
+
default_selects = defaults[:select] || {}
|
32
|
+
attributes = default_selects[method.try(:to_sym)] || default_selects[:all] || []
|
33
|
+
attributes.is_a?(Proc) ? instance_exec(&attributes) : attributes
|
34
|
+
end
|
29
35
|
|
30
|
-
|
31
|
-
@target = @target.select(attributes || get_default_select_attributes)
|
32
|
-
end
|
36
|
+
private
|
33
37
|
|
34
|
-
|
35
|
-
|
36
|
-
# or a lambdas/procs to execute to return an array of attribute names
|
37
|
-
def get_default_select_attributes
|
38
|
-
default_selects = defaults[:select] || {}
|
39
|
-
attributes = default_selects[@current_method] || default_selects[:all] || []
|
40
|
-
attributes.is_a?(Proc) ? instance_exec(&attributes) : attributes
|
41
|
-
end
|
38
|
+
def select(attributes)
|
39
|
+
@target = @target.select(attributes || default_select)
|
42
40
|
end
|
43
41
|
end
|
44
42
|
end
|
@@ -20,29 +20,29 @@ module ActiveManageable
|
|
20
20
|
|
21
21
|
included do
|
22
22
|
class_attribute :unique_search, instance_writer: false, instance_predicate: false
|
23
|
+
end
|
23
24
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
when Hash
|
33
|
-
evaluate_condition(*unique_search.first)
|
34
|
-
end
|
25
|
+
def unique_search?
|
26
|
+
case unique_search
|
27
|
+
when nil
|
28
|
+
false
|
29
|
+
when TrueClass, FalseClass
|
30
|
+
unique_search
|
31
|
+
when Hash
|
32
|
+
evaluate_condition(*unique_search.first)
|
35
33
|
end
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
36
37
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
end
|
44
|
-
condition == :if ? result : !result
|
38
|
+
def evaluate_condition(condition, method)
|
39
|
+
result = case method
|
40
|
+
when Symbol
|
41
|
+
method(method).call
|
42
|
+
when Proc
|
43
|
+
instance_exec(&method)
|
45
44
|
end
|
45
|
+
condition == :if ? result : !result
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -5,16 +5,31 @@ module ActiveManageable
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
include ActiveManageable::Methods::Auxiliary::ModelAttributes
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
def create(attributes:)
|
11
|
+
initialize_state(attributes: attributes)
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
@target = build_object_for_create
|
14
|
+
authorize(record: @target)
|
14
15
|
|
15
|
-
|
16
|
+
model_class.transaction do
|
17
|
+
yield if block_given?
|
18
|
+
create_object
|
19
|
+
rescue ActiveRecord::RecordInvalid
|
20
|
+
false
|
16
21
|
end
|
17
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def build_object_for_create
|
27
|
+
action_scope.new(attribute_values)
|
28
|
+
end
|
29
|
+
|
30
|
+
def create_object
|
31
|
+
@target.save!
|
32
|
+
end
|
18
33
|
end
|
19
34
|
end
|
20
35
|
end
|
@@ -5,19 +5,34 @@ module ActiveManageable
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
include ActiveManageable::Methods::Auxiliary::Includes
|
8
|
+
end
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
def destroy(id:, options: {})
|
11
|
+
initialize_state(options: options)
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
@target = action_scope
|
14
|
+
includes(@options[:includes])
|
14
15
|
|
15
|
-
|
16
|
-
|
16
|
+
@target = find_object_for_destroy(id: id)
|
17
|
+
authorize(record: @target)
|
17
18
|
|
18
|
-
|
19
|
+
model_class.transaction do
|
20
|
+
yield if block_given?
|
21
|
+
destroy_object
|
22
|
+
rescue ActiveRecord::RecordNotDestroyed
|
23
|
+
false
|
19
24
|
end
|
20
25
|
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def find_object_for_destroy(id:)
|
30
|
+
@target.find(id)
|
31
|
+
end
|
32
|
+
|
33
|
+
def destroy_object
|
34
|
+
@target.destroy!
|
35
|
+
end
|
21
36
|
end
|
22
37
|
end
|
23
38
|
end
|
@@ -6,19 +6,27 @@ module ActiveManageable
|
|
6
6
|
included do
|
7
7
|
include ActiveManageable::Methods::Auxiliary::Includes
|
8
8
|
include ActiveManageable::Methods::Auxiliary::Select
|
9
|
+
end
|
10
|
+
|
11
|
+
def edit(id:, options: {})
|
12
|
+
initialize_state(options: options)
|
13
|
+
|
14
|
+
@target = action_scope
|
15
|
+
includes(@options[:includes])
|
16
|
+
select(@options[:select])
|
9
17
|
|
10
|
-
|
11
|
-
initialize_state(options: options)
|
18
|
+
yield if block_given?
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
@target = find_object_for_edit(id: id)
|
21
|
+
authorize(record: @target)
|
22
|
+
|
23
|
+
@target
|
24
|
+
end
|
16
25
|
|
17
|
-
|
18
|
-
authorize(record: @target)
|
26
|
+
private
|
19
27
|
|
20
|
-
|
21
|
-
|
28
|
+
def find_object_for_edit(id:)
|
29
|
+
@target.find(id)
|
22
30
|
end
|
23
31
|
end
|
24
32
|
end
|
@@ -9,40 +9,42 @@ module ActiveManageable
|
|
9
9
|
include ActiveManageable::Methods::Auxiliary::Includes
|
10
10
|
include ActiveManageable::Methods::Auxiliary::Select
|
11
11
|
include ActiveManageable::Methods::Auxiliary::UniqueSearch
|
12
|
+
end
|
13
|
+
|
14
|
+
def index(options: {})
|
15
|
+
initialize_state(options: options)
|
12
16
|
|
13
|
-
|
14
|
-
|
17
|
+
@target = authorization_scope
|
18
|
+
authorize(record: model_class)
|
19
|
+
search(@options[:search])
|
20
|
+
order(@options[:order])
|
21
|
+
scopes(@options[:scopes])
|
22
|
+
page(@options[:page])
|
23
|
+
includes(@options[:includes])
|
24
|
+
select(@options[:select])
|
25
|
+
distinct(unique_search?)
|
15
26
|
|
16
|
-
|
17
|
-
authorize(record: model_class)
|
18
|
-
search(@options[:search])
|
19
|
-
order(@options[:order])
|
20
|
-
scopes(@options[:scopes])
|
21
|
-
page(@options[:page])
|
22
|
-
includes(@options[:includes])
|
23
|
-
select(@options[:select])
|
24
|
-
distinct(unique_search?)
|
27
|
+
yield if block_given?
|
25
28
|
|
26
|
-
|
27
|
-
|
29
|
+
@target
|
30
|
+
end
|
28
31
|
|
29
|
-
|
32
|
+
private
|
30
33
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
+
def authorization_scope
|
35
|
+
action_scope
|
36
|
+
end
|
34
37
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
+
def search(opts)
|
39
|
+
@target
|
40
|
+
end
|
38
41
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
+
def page(opts)
|
43
|
+
@target
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
46
|
+
def distinct(value)
|
47
|
+
@target = target.distinct(value)
|
46
48
|
end
|
47
49
|
end
|
48
50
|
end
|
@@ -5,15 +5,23 @@ module ActiveManageable
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
include ActiveManageable::Methods::Auxiliary::ModelAttributes
|
8
|
+
end
|
9
|
+
|
10
|
+
def new(attributes: {})
|
11
|
+
initialize_state(attributes: attributes)
|
12
|
+
|
13
|
+
@target = build_object_for_new
|
14
|
+
authorize(record: @target)
|
8
15
|
|
9
|
-
|
10
|
-
|
16
|
+
yield if block_given?
|
17
|
+
|
18
|
+
@target
|
19
|
+
end
|
11
20
|
|
12
|
-
|
13
|
-
authorize(record: @target)
|
21
|
+
private
|
14
22
|
|
15
|
-
|
16
|
-
|
23
|
+
def build_object_for_new
|
24
|
+
action_scope.new(attribute_values)
|
17
25
|
end
|
18
26
|
end
|
19
27
|
end
|
@@ -6,19 +6,27 @@ module ActiveManageable
|
|
6
6
|
included do
|
7
7
|
include ActiveManageable::Methods::Auxiliary::Includes
|
8
8
|
include ActiveManageable::Methods::Auxiliary::Select
|
9
|
+
end
|
10
|
+
|
11
|
+
def show(id:, options: {})
|
12
|
+
initialize_state(options: options)
|
13
|
+
|
14
|
+
@target = action_scope
|
15
|
+
includes(@options[:includes])
|
16
|
+
select(@options[:select])
|
9
17
|
|
10
|
-
|
11
|
-
initialize_state(options: options)
|
18
|
+
yield if block_given?
|
12
19
|
|
13
|
-
|
14
|
-
|
15
|
-
|
20
|
+
@target = find_object_for_show(id: id)
|
21
|
+
authorize(record: @target)
|
22
|
+
|
23
|
+
@target
|
24
|
+
end
|
16
25
|
|
17
|
-
|
18
|
-
authorize(record: @target)
|
26
|
+
private
|
19
27
|
|
20
|
-
|
21
|
-
|
28
|
+
def find_object_for_show(id:)
|
29
|
+
@target.find(id)
|
22
30
|
end
|
23
31
|
end
|
24
32
|
end
|
@@ -5,19 +5,40 @@ module ActiveManageable
|
|
5
5
|
|
6
6
|
included do
|
7
7
|
include ActiveManageable::Methods::Auxiliary::Includes
|
8
|
+
end
|
9
|
+
|
10
|
+
def update(id:, attributes:, options: {})
|
11
|
+
initialize_state(attributes: attributes, options: options)
|
8
12
|
|
9
|
-
|
10
|
-
|
13
|
+
@target = action_scope
|
14
|
+
includes(@options[:includes])
|
11
15
|
|
12
|
-
|
13
|
-
|
16
|
+
@target = find_object_for_update(id: id)
|
17
|
+
authorize(record: @target)
|
14
18
|
|
15
|
-
|
16
|
-
authorize(record: @target)
|
19
|
+
assign_attributes_for_update
|
17
20
|
|
18
|
-
|
21
|
+
model_class.transaction do
|
22
|
+
yield if block_given?
|
23
|
+
update_object
|
24
|
+
rescue ActiveRecord::RecordInvalid
|
25
|
+
false
|
19
26
|
end
|
20
27
|
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def find_object_for_update(id:)
|
32
|
+
@target.find(id)
|
33
|
+
end
|
34
|
+
|
35
|
+
def assign_attributes_for_update
|
36
|
+
@target.assign_attributes(@attributes)
|
37
|
+
end
|
38
|
+
|
39
|
+
def update_object
|
40
|
+
@target.save!
|
41
|
+
end
|
21
42
|
end
|
22
43
|
end
|
23
44
|
end
|
@@ -17,22 +17,42 @@ module ActiveManageable
|
|
17
17
|
def default_page_size(page_size)
|
18
18
|
defaults[:page] = {size: page_size.to_i}
|
19
19
|
end
|
20
|
+
|
21
|
+
# Class option used when determining whether to create a paginatable collection without counting the total number of records
|
22
|
+
# within the order of precedence based on the (1) method option, or (2) class option, or (3) configuration option
|
23
|
+
def paginate_without_count(without_count = true)
|
24
|
+
self.without_count = without_count
|
25
|
+
end
|
20
26
|
end
|
21
27
|
|
22
28
|
included do
|
23
|
-
|
29
|
+
class_attribute :without_count, instance_writer: false, instance_predicate: false
|
30
|
+
end
|
24
31
|
|
25
|
-
|
26
|
-
@target = @target.page(page_number(opts)).per(page_size(opts))
|
27
|
-
end
|
32
|
+
private
|
28
33
|
|
29
|
-
|
30
|
-
|
34
|
+
def page(opts)
|
35
|
+
@target = @target.page(page_number(opts)).per(page_size(opts)).tap do |target|
|
36
|
+
target.without_count if paginate_without_count?(opts)
|
31
37
|
end
|
38
|
+
end
|
32
39
|
|
33
|
-
|
34
|
-
|
35
|
-
|
40
|
+
def page_number(opts)
|
41
|
+
opts.try(:[], :number)
|
42
|
+
end
|
43
|
+
|
44
|
+
def page_size(opts)
|
45
|
+
opts.try(:[], :size) || defaults.dig(:page, :size)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Determine whether to create a paginatable collection without counting the total number of records
|
49
|
+
# in order of precedence based on the (1) method option, or (2) class option, or (3) configuration option
|
50
|
+
def paginate_without_count?(opts)
|
51
|
+
[
|
52
|
+
opts.try(:[], :without_count),
|
53
|
+
without_count,
|
54
|
+
ActiveManageable.configuration.paginate_without_count
|
55
|
+
].compact.first
|
36
56
|
end
|
37
57
|
end
|
38
58
|
end
|
@@ -11,26 +11,24 @@ module ActiveManageable
|
|
11
11
|
attr_reader :ransack
|
12
12
|
|
13
13
|
initialize_state_methods :initialize_ransack_state
|
14
|
+
end
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
@ransack = nil
|
19
|
-
end
|
16
|
+
def initialize_ransack_state
|
17
|
+
@ransack = nil
|
18
|
+
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
20
|
+
def search(opts)
|
21
|
+
@ransack = @target.ransack(opts)
|
22
|
+
@target = @ransack.result
|
23
|
+
end
|
25
24
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
end
|
25
|
+
# Perform standard index module ordering when no ransack search params provided
|
26
|
+
# or no ransack sorts params provided
|
27
|
+
def order(attributes)
|
28
|
+
if @ransack.blank? || @ransack.sorts.empty?
|
29
|
+
@target = @target.order(order_attributes(attributes))
|
30
|
+
else
|
31
|
+
@target
|
34
32
|
end
|
35
33
|
end
|
36
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_manageable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Hilton
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2022-
|
12
|
+
date: 2022-09-27 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|