inquery 1.0.11 → 1.1.0
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 +4 -4
- data/.github/workflows/rubocop.yml +1 -1
- data/.github/workflows/ruby.yml +24 -8
- data/.gitignore +2 -2
- data/.rubocop.yml +4 -0
- data/Appraisals +24 -4
- data/CHANGELOG.md +38 -0
- data/Gemfile +17 -1
- data/Gemfile.lock +125 -0
- data/LICENSE +1 -1
- data/MIGRATION.md +260 -0
- data/README.md +14 -8
- data/RUBY_VERSION +1 -1
- data/Rakefile +4 -11
- data/VERSION +1 -1
- data/doc/Inquery/Exceptions/Base.html +4 -4
- data/doc/Inquery/Exceptions/InvalidRelation.html +4 -4
- data/doc/Inquery/Exceptions/UnknownCallSignature.html +4 -4
- data/doc/Inquery/Exceptions.html +4 -4
- data/doc/Inquery/MethodAccessibleHash.html +431 -0
- data/doc/Inquery/Mixins/RawSqlUtils.html +17 -4
- data/doc/Inquery/Mixins/RelationValidation/ClassMethods.html +8 -7
- data/doc/Inquery/Mixins/RelationValidation.html +9 -8
- data/doc/Inquery/Mixins/SchemaValidation/ClassMethods.html +4 -4
- data/doc/Inquery/Mixins/SchemaValidation.html +4 -4
- data/doc/Inquery/Mixins.html +4 -4
- data/doc/Inquery/Query/Chainable.html +207 -90
- data/doc/Inquery/Query.html +401 -73
- data/doc/Inquery.html +12 -9
- data/doc/_index.html +12 -5
- data/doc/class_list.html +6 -3
- data/doc/css/full_list.css +3 -3
- data/doc/css/style.css +6 -0
- data/doc/file.README.html +102 -16
- data/doc/file_list.html +5 -2
- data/doc/frames.html +10 -5
- data/doc/index.html +102 -16
- data/doc/js/app.js +294 -264
- data/doc/js/full_list.js +30 -4
- data/doc/method_list.html +48 -21
- data/doc/top-level-namespace.html +4 -4
- data/gemfiles/rails_5.2.gemfile +1 -0
- data/gemfiles/rails_6.0.gemfile +1 -0
- data/gemfiles/rails_6.1.gemfile +1 -0
- data/gemfiles/rails_7.0.gemfile +1 -0
- data/gemfiles/{rails_5.1.gemfile → rails_7.1.gemfile} +2 -1
- data/gemfiles/rails_7.2.gemfile +8 -0
- data/gemfiles/rails_8.0.gemfile +8 -0
- data/gemfiles/rails_8.1.gemfile +8 -0
- data/inquery.gemspec +11 -34
- data/lib/inquery/method_accessible_hash.rb +45 -0
- data/lib/inquery/mixins/raw_sql_utils.rb +32 -6
- data/lib/inquery/mixins/relation_validation.rb +1 -1
- data/lib/inquery/query/chainable.rb +69 -27
- data/lib/inquery/query.rb +67 -14
- data/lib/inquery.rb +2 -0
- data/test/inquery/error_handling_test.rb +117 -0
- data/test/inquery/method_accessible_hash_test.rb +85 -0
- data/test/inquery/mixins/raw_sql_utils_test.rb +67 -0
- data/test/inquery/query/chainable_test.rb +78 -0
- data/test/inquery/query_test.rb +86 -0
- data/test/test_helper.rb +11 -0
- metadata +30 -129
- data/.yardopts +0 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 45b9f4f89d241cb824f7de46f3b84049091ff579853165562df4341765c9e536
|
|
4
|
+
data.tar.gz: '028f2cd61072b3ffbfd31b2b626380d056805670483fad333f22da17ebe8e5c1'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c52b88733d60d5db5c071464bba3e80658c9bb2653e8624df96637c74dcfbde157cd59444e2a34fce8b971ba5267b9c70aaacc12e76c51d0ffabe5869f7c122b
|
|
7
|
+
data.tar.gz: fee01595c30949c3dc6889d8b9d7c9e931f05ae45857476a7af3ec4bf88dbce19f3faeae666505d1ccb09eee04f6a615ce993f47b2373987f6fa18d3d6ee59b6
|
data/.github/workflows/ruby.yml
CHANGED
|
@@ -13,20 +13,12 @@ jobs:
|
|
|
13
13
|
fail-fast: false
|
|
14
14
|
matrix:
|
|
15
15
|
include:
|
|
16
|
-
- rails-version: '5.1'
|
|
17
|
-
ruby-version: '2.5.1'
|
|
18
|
-
- rails-version: '5.2'
|
|
19
|
-
ruby-version: '2.5.1'
|
|
20
16
|
- rails-version: '5.2'
|
|
21
17
|
ruby-version: '2.6.2'
|
|
22
|
-
- rails-version: '6.0'
|
|
23
|
-
ruby-version: '2.5.1'
|
|
24
18
|
- rails-version: '6.0'
|
|
25
19
|
ruby-version: '2.6.2'
|
|
26
20
|
- rails-version: '6.0'
|
|
27
21
|
ruby-version: '2.7.1'
|
|
28
|
-
- rails-version: '6.1'
|
|
29
|
-
ruby-version: '2.5.1'
|
|
30
22
|
- rails-version: '6.1'
|
|
31
23
|
ruby-version: '2.6.2'
|
|
32
24
|
- rails-version: '6.1'
|
|
@@ -39,6 +31,30 @@ jobs:
|
|
|
39
31
|
ruby-version: '3.0.1'
|
|
40
32
|
- rails-version: '7.0'
|
|
41
33
|
ruby-version: '3.1.0'
|
|
34
|
+
- rails-version: '7.0'
|
|
35
|
+
ruby-version: '3.2.0'
|
|
36
|
+
- rails-version: '7.0'
|
|
37
|
+
ruby-version: '3.3.0'
|
|
38
|
+
- rails-version: '7.1'
|
|
39
|
+
ruby-version: '3.1.0'
|
|
40
|
+
- rails-version: '7.1'
|
|
41
|
+
ruby-version: '3.2.0'
|
|
42
|
+
- rails-version: '7.1'
|
|
43
|
+
ruby-version: '3.3.0'
|
|
44
|
+
- rails-version: '7.2'
|
|
45
|
+
ruby-version: '3.2.0'
|
|
46
|
+
- rails-version: '7.2'
|
|
47
|
+
ruby-version: '3.3.0'
|
|
48
|
+
- rails-version: '7.2'
|
|
49
|
+
ruby-version: '3.4.1'
|
|
50
|
+
- rails-version: '8.0'
|
|
51
|
+
ruby-version: '3.3.0'
|
|
52
|
+
- rails-version: '8.0'
|
|
53
|
+
ruby-version: '3.4.1'
|
|
54
|
+
- rails-version: '8.1'
|
|
55
|
+
ruby-version: '3.3.0'
|
|
56
|
+
- rails-version: '8.1'
|
|
57
|
+
ruby-version: '3.4.1'
|
|
42
58
|
name: Test against Ruby ${{ matrix.ruby-version }} / Rails ${{ matrix.rails-version }}
|
|
43
59
|
env:
|
|
44
60
|
BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/rails_${{ matrix.rails-version }}.gemfile
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
|
@@ -5,6 +5,7 @@ AllCops:
|
|
|
5
5
|
- 'vendor/**/*'
|
|
6
6
|
- 'tmp/**/*'
|
|
7
7
|
- 'inquery.gemspec'
|
|
8
|
+
- 'gemfiles/**/*'
|
|
8
9
|
SuggestExtensions: false
|
|
9
10
|
|
|
10
11
|
DisplayCopNames: true
|
|
@@ -105,3 +106,6 @@ Style/CaseLikeIf:
|
|
|
105
106
|
|
|
106
107
|
Style/OpenStructUse:
|
|
107
108
|
Enabled: false
|
|
109
|
+
|
|
110
|
+
Style/ArgumentsForwarding:
|
|
111
|
+
Enabled: false
|
data/Appraisals
CHANGED
|
@@ -1,19 +1,39 @@
|
|
|
1
|
+
appraise 'rails-8.1' do
|
|
2
|
+
gem 'rails', '~> 8.1.0'
|
|
3
|
+
gem 'sqlite3', '>= 2.5'
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
appraise 'rails-8.0' do
|
|
7
|
+
gem 'rails', '~> 8.0.0'
|
|
8
|
+
gem 'sqlite3', '>= 2.5'
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
appraise 'rails-7.2' do
|
|
12
|
+
gem 'rails', '~> 7.2.0'
|
|
13
|
+
gem 'sqlite3', '>= 2.5'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
appraise 'rails-7.1' do
|
|
17
|
+
gem 'rails', '~> 7.1.0'
|
|
18
|
+
gem 'sqlite3', '>= 1.4'
|
|
19
|
+
end
|
|
20
|
+
|
|
1
21
|
appraise 'rails-7.0' do
|
|
2
22
|
gem 'rails', '~> 7.0.1'
|
|
23
|
+
gem 'sqlite3', '~> 1.4.0'
|
|
3
24
|
end
|
|
4
25
|
|
|
5
26
|
appraise 'rails-6.1' do
|
|
6
27
|
gem 'rails', '~> 6.1.4'
|
|
28
|
+
gem 'sqlite3', '~> 1.4.0'
|
|
7
29
|
end
|
|
8
30
|
|
|
9
31
|
appraise 'rails-6.0' do
|
|
10
32
|
gem 'rails', '~> 6.0.4'
|
|
33
|
+
gem 'sqlite3', '~> 1.4.0'
|
|
11
34
|
end
|
|
12
35
|
|
|
13
36
|
appraise 'rails-5.2' do
|
|
14
37
|
gem 'rails', '~> 5.2.6'
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
appraise 'rails-5.1' do
|
|
18
|
-
gem 'rails', '~> 5.1.7'
|
|
38
|
+
gem 'sqlite3', '~> 1.3.13'
|
|
19
39
|
end
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
1
|
# Change log
|
|
2
2
|
|
|
3
|
+
## 1.1.0 (2026-01-05)
|
|
4
|
+
|
|
5
|
+
* **Drop support for Ruby 2.5.1 and Rails 5.1**: The minimum supported versions
|
|
6
|
+
are now Ruby 2.6.2 and Rails 5.2. Ruby 2.5.1 reached end-of-life in March
|
|
7
|
+
2021 and is no longer available on modern CI infrastructure (Ubuntu 24.04).
|
|
8
|
+
* Fix Ruby 2.6 compatibility in `MethodAccessibleHash` by converting method
|
|
9
|
+
symbol to string before calling `end_with?` (`Symbol#end_with?` was added
|
|
10
|
+
in Ruby 2.7)
|
|
11
|
+
* Fix Ruby 2.5/2.6 compatibility by replacing argument forwarding syntax (`...`)
|
|
12
|
+
with explicit `*args, &block` in schema validation mixin
|
|
13
|
+
* Add inline documentation to Query, Query::Chainable, and RawSqlUtils classes
|
|
14
|
+
* Add MIGRATION.md guide with examples for migrating from raw ActiveRecord
|
|
15
|
+
queries and upgrading between Inquery versions
|
|
16
|
+
* Refactor argument parsing in `Query::Chainable` for improved readability and
|
|
17
|
+
maintainability while preserving backward compatibility
|
|
18
|
+
* Increase test coverage from 87.1% to 90.97% by adding tests for error
|
|
19
|
+
handling, relation validation edge cases, and schema validation
|
|
20
|
+
* Add integration tests for RawSqlUtils mixin (`san` and `exec_query` methods)
|
|
21
|
+
* Move all development dependencies from gemspec to Gemfile for cleaner
|
|
22
|
+
separation of runtime and development dependencies
|
|
23
|
+
* Remove unused dependencies: `yard`, `haml`, and `redcarpet`
|
|
24
|
+
* Remove YARD documentation files and configuration
|
|
25
|
+
* Update RuboCop from version 1.25 to ~> 1.60 and fix new style violations
|
|
26
|
+
* Replace deprecated `OpenStruct` with `MethodAccessibleHash` to ensure
|
|
27
|
+
compatibility with Ruby 3.5+
|
|
28
|
+
* Remove debug code from `Query::Chainable#call` method
|
|
29
|
+
* Fix Ruby 3.0+ compatibility by explicitly requiring `logger`
|
|
30
|
+
* Constrain `sqlite3` to version `~> 1.4.0` for Rails 6.1 and 7.0 to avoid
|
|
31
|
+
version conflicts
|
|
32
|
+
* Update `RUBY_VERSION` to `ruby-3.3.5`
|
|
33
|
+
* Add support for Rails 7.1, 7.2, 8.0, and 8.1
|
|
34
|
+
* Add support for Ruby 3.2, 3.3, and 3.4
|
|
35
|
+
* Update sqlite3 gem requirement to `>= 2.5` for Rails 7.2+ to ensure Ruby
|
|
36
|
+
3.4 compatibility
|
|
37
|
+
* Add explicit version constraints for runtime dependencies: `activesupport`
|
|
38
|
+
and `activerecord` now require `>= 5.1`, `schemacop` allows `>= 3.0.8, < 4.0`
|
|
39
|
+
for better dependency resolution and compatibility
|
|
40
|
+
|
|
3
41
|
## 1.0.11 (2023-08-24)
|
|
4
42
|
|
|
5
43
|
* Add configuration option `config.default_schema_version` that allows you to
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,20 @@
|
|
|
1
1
|
source 'https://rubygems.org'
|
|
2
2
|
|
|
3
|
-
# Specify
|
|
3
|
+
# Specify runtime dependencies in the .gemspec file
|
|
4
4
|
gemspec
|
|
5
|
+
|
|
6
|
+
# Development dependencies
|
|
7
|
+
group :development do
|
|
8
|
+
gem 'appraisal'
|
|
9
|
+
gem 'rake'
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
group :test do
|
|
13
|
+
gem 'minitest'
|
|
14
|
+
gem 'simplecov'
|
|
15
|
+
gem 'sqlite3'
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
group :lint do
|
|
19
|
+
gem 'rubocop', '~> 1.60'
|
|
20
|
+
end
|
data/Gemfile.lock
ADDED
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
PATH
|
|
2
|
+
remote: .
|
|
3
|
+
specs:
|
|
4
|
+
inquery (1.1.0)
|
|
5
|
+
activerecord (>= 5.1)
|
|
6
|
+
activesupport (>= 5.1)
|
|
7
|
+
schemacop (>= 3.0.8, < 4.0)
|
|
8
|
+
|
|
9
|
+
GEM
|
|
10
|
+
remote: https://rubygems.org/
|
|
11
|
+
specs:
|
|
12
|
+
activemodel (8.1.1)
|
|
13
|
+
activesupport (= 8.1.1)
|
|
14
|
+
activerecord (8.1.1)
|
|
15
|
+
activemodel (= 8.1.1)
|
|
16
|
+
activesupport (= 8.1.1)
|
|
17
|
+
timeout (>= 0.4.0)
|
|
18
|
+
activesupport (8.1.1)
|
|
19
|
+
base64
|
|
20
|
+
bigdecimal
|
|
21
|
+
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
22
|
+
connection_pool (>= 2.2.5)
|
|
23
|
+
drb
|
|
24
|
+
i18n (>= 1.6, < 2)
|
|
25
|
+
json
|
|
26
|
+
logger (>= 1.4.2)
|
|
27
|
+
minitest (>= 5.1)
|
|
28
|
+
securerandom (>= 0.3)
|
|
29
|
+
tzinfo (~> 2.0, >= 2.0.5)
|
|
30
|
+
uri (>= 0.13.1)
|
|
31
|
+
appraisal (2.5.0)
|
|
32
|
+
bundler
|
|
33
|
+
rake
|
|
34
|
+
thor (>= 0.14.0)
|
|
35
|
+
ast (2.4.3)
|
|
36
|
+
base64 (0.3.0)
|
|
37
|
+
bigdecimal (3.3.1)
|
|
38
|
+
concurrent-ruby (1.3.5)
|
|
39
|
+
connection_pool (2.5.5)
|
|
40
|
+
docile (1.4.1)
|
|
41
|
+
drb (2.2.3)
|
|
42
|
+
i18n (1.14.7)
|
|
43
|
+
concurrent-ruby (~> 1.0)
|
|
44
|
+
json (2.16.0)
|
|
45
|
+
language_server-protocol (3.17.0.5)
|
|
46
|
+
lint_roller (1.1.0)
|
|
47
|
+
logger (1.7.0)
|
|
48
|
+
minitest (5.26.2)
|
|
49
|
+
parallel (1.27.0)
|
|
50
|
+
parser (3.3.10.0)
|
|
51
|
+
ast (~> 2.4.1)
|
|
52
|
+
racc
|
|
53
|
+
prism (1.6.0)
|
|
54
|
+
racc (1.8.1)
|
|
55
|
+
rainbow (3.1.1)
|
|
56
|
+
rake (13.3.1)
|
|
57
|
+
regexp_parser (2.11.3)
|
|
58
|
+
rubocop (1.81.7)
|
|
59
|
+
json (~> 2.3)
|
|
60
|
+
language_server-protocol (~> 3.17.0.2)
|
|
61
|
+
lint_roller (~> 1.1.0)
|
|
62
|
+
parallel (~> 1.10)
|
|
63
|
+
parser (>= 3.3.0.2)
|
|
64
|
+
rainbow (>= 2.2.2, < 4.0)
|
|
65
|
+
regexp_parser (>= 2.9.3, < 3.0)
|
|
66
|
+
rubocop-ast (>= 1.47.1, < 2.0)
|
|
67
|
+
ruby-progressbar (~> 1.7)
|
|
68
|
+
unicode-display_width (>= 2.4.0, < 4.0)
|
|
69
|
+
rubocop-ast (1.48.0)
|
|
70
|
+
parser (>= 3.3.7.2)
|
|
71
|
+
prism (~> 1.4)
|
|
72
|
+
ruby-progressbar (1.13.0)
|
|
73
|
+
ruby2_keywords (0.0.5)
|
|
74
|
+
schemacop (3.0.35)
|
|
75
|
+
activesupport (>= 4.0)
|
|
76
|
+
ruby2_keywords (>= 0.0.4)
|
|
77
|
+
securerandom (0.4.1)
|
|
78
|
+
simplecov (0.22.0)
|
|
79
|
+
docile (~> 1.1)
|
|
80
|
+
simplecov-html (~> 0.11)
|
|
81
|
+
simplecov_json_formatter (~> 0.1)
|
|
82
|
+
simplecov-html (0.13.2)
|
|
83
|
+
simplecov_json_formatter (0.1.4)
|
|
84
|
+
sqlite3 (2.8.1-aarch64-linux-gnu)
|
|
85
|
+
sqlite3 (2.8.1-aarch64-linux-musl)
|
|
86
|
+
sqlite3 (2.8.1-arm-linux-gnu)
|
|
87
|
+
sqlite3 (2.8.1-arm-linux-musl)
|
|
88
|
+
sqlite3 (2.8.1-arm64-darwin)
|
|
89
|
+
sqlite3 (2.8.1-x86-linux-gnu)
|
|
90
|
+
sqlite3 (2.8.1-x86-linux-musl)
|
|
91
|
+
sqlite3 (2.8.1-x86_64-darwin)
|
|
92
|
+
sqlite3 (2.8.1-x86_64-linux-gnu)
|
|
93
|
+
sqlite3 (2.8.1-x86_64-linux-musl)
|
|
94
|
+
thor (1.4.0)
|
|
95
|
+
timeout (0.4.4)
|
|
96
|
+
tzinfo (2.0.6)
|
|
97
|
+
concurrent-ruby (~> 1.0)
|
|
98
|
+
unicode-display_width (3.2.0)
|
|
99
|
+
unicode-emoji (~> 4.1)
|
|
100
|
+
unicode-emoji (4.1.0)
|
|
101
|
+
uri (1.1.1)
|
|
102
|
+
|
|
103
|
+
PLATFORMS
|
|
104
|
+
aarch64-linux-gnu
|
|
105
|
+
aarch64-linux-musl
|
|
106
|
+
arm-linux-gnu
|
|
107
|
+
arm-linux-musl
|
|
108
|
+
arm64-darwin
|
|
109
|
+
x86-linux-gnu
|
|
110
|
+
x86-linux-musl
|
|
111
|
+
x86_64-darwin
|
|
112
|
+
x86_64-linux-gnu
|
|
113
|
+
x86_64-linux-musl
|
|
114
|
+
|
|
115
|
+
DEPENDENCIES
|
|
116
|
+
appraisal
|
|
117
|
+
inquery!
|
|
118
|
+
minitest
|
|
119
|
+
rake
|
|
120
|
+
rubocop (~> 1.60)
|
|
121
|
+
simplecov
|
|
122
|
+
sqlite3
|
|
123
|
+
|
|
124
|
+
BUNDLED WITH
|
|
125
|
+
2.5.18
|
data/LICENSE
CHANGED
data/MIGRATION.md
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# Migration Guide
|
|
2
|
+
|
|
3
|
+
This guide helps you migrate from raw ActiveRecord queries to Inquery query classes, and between different versions of Inquery.
|
|
4
|
+
|
|
5
|
+
## Migrating from Raw ActiveRecord Queries
|
|
6
|
+
|
|
7
|
+
### Simple Query
|
|
8
|
+
|
|
9
|
+
**Before (raw ActiveRecord):**
|
|
10
|
+
```ruby
|
|
11
|
+
# In controller or service
|
|
12
|
+
def active_users
|
|
13
|
+
User.where(active: true).order(:name)
|
|
14
|
+
end
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**After (Inquery):**
|
|
18
|
+
```ruby
|
|
19
|
+
# app/queries/fetch_active_users.rb
|
|
20
|
+
class FetchActiveUsers < Inquery::Query
|
|
21
|
+
def call
|
|
22
|
+
User.where(active: true).order(:name)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# In controller or service
|
|
27
|
+
def active_users
|
|
28
|
+
FetchActiveUsers.run
|
|
29
|
+
end
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**Benefits:**
|
|
33
|
+
- Reusable across controllers, services, and background jobs
|
|
34
|
+
- Testable in isolation
|
|
35
|
+
- Named and documented
|
|
36
|
+
|
|
37
|
+
### Parameterized Query
|
|
38
|
+
|
|
39
|
+
**Before (raw ActiveRecord):**
|
|
40
|
+
```ruby
|
|
41
|
+
def users_by_status(status)
|
|
42
|
+
User.where(status: status).order(:created_at)
|
|
43
|
+
end
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**After (Inquery with schema validation):**
|
|
47
|
+
```ruby
|
|
48
|
+
class FetchUsersByStatus < Inquery::Query
|
|
49
|
+
schema3 do
|
|
50
|
+
str! :status
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def call
|
|
54
|
+
User.where(status: osparams.status).order(:created_at)
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Usage
|
|
59
|
+
FetchUsersByStatus.run(status: 'active')
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Benefits:**
|
|
63
|
+
- Automatic parameter validation
|
|
64
|
+
- Type checking
|
|
65
|
+
- Clear API documentation through schema
|
|
66
|
+
|
|
67
|
+
### Complex Query with Post-Processing
|
|
68
|
+
|
|
69
|
+
**Before:**
|
|
70
|
+
```ruby
|
|
71
|
+
def user_statistics
|
|
72
|
+
users = User.where(active: true)
|
|
73
|
+
{
|
|
74
|
+
total: users.count,
|
|
75
|
+
premium: users.where(plan: 'premium').count
|
|
76
|
+
}
|
|
77
|
+
end
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**After:**
|
|
81
|
+
```ruby
|
|
82
|
+
class FetchUserStatistics < Inquery::Query
|
|
83
|
+
def call
|
|
84
|
+
User.where(active: true)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def process(users)
|
|
88
|
+
{
|
|
89
|
+
total: users.count,
|
|
90
|
+
premium: users.where(plan: 'premium').count
|
|
91
|
+
}
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Benefits:**
|
|
97
|
+
- Separation of query logic and data transformation
|
|
98
|
+
- Can call with 'call' to get raw results or 'run' for processed results
|
|
99
|
+
|
|
100
|
+
### Scope to Chainable Query
|
|
101
|
+
|
|
102
|
+
**Before:**
|
|
103
|
+
```ruby
|
|
104
|
+
class User < ActiveRecord::Base
|
|
105
|
+
scope :active, -> { where(active: true) }
|
|
106
|
+
scope :premium, -> { where(plan: 'premium') }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Usage
|
|
110
|
+
User.active.premium
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**After:**
|
|
114
|
+
```ruby
|
|
115
|
+
class FetchActiveUsers < Inquery::Query::Chainable
|
|
116
|
+
relation class: 'User'
|
|
117
|
+
|
|
118
|
+
def call
|
|
119
|
+
relation.where(active: true)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
class FetchPremiumUsers < Inquery::Query::Chainable
|
|
124
|
+
relation class: 'User'
|
|
125
|
+
|
|
126
|
+
def call
|
|
127
|
+
relation.where(plan: 'premium')
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Usage as query classes
|
|
132
|
+
FetchPremiumUsers.run(FetchActiveUsers.run)
|
|
133
|
+
|
|
134
|
+
# Or register as scopes
|
|
135
|
+
class User < ActiveRecord::Base
|
|
136
|
+
scope :active, FetchActiveUsers
|
|
137
|
+
scope :premium, FetchPremiumUsers
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
User.active.premium
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
**Benefits:**
|
|
144
|
+
- Full Ruby classes instead of lambdas
|
|
145
|
+
- Can add tests, documentation, and complex logic
|
|
146
|
+
- Chainable and composable
|
|
147
|
+
|
|
148
|
+
## Schema Validation: Schemacop v2 vs v3
|
|
149
|
+
|
|
150
|
+
Inquery supports both Schemacop v2 and v3 schemas. The default is v2 for backward compatibility.
|
|
151
|
+
|
|
152
|
+
### Using Schemacop v2 (default)
|
|
153
|
+
|
|
154
|
+
```ruby
|
|
155
|
+
class FetchUsers < Inquery::Query
|
|
156
|
+
schema do
|
|
157
|
+
req :status, :string
|
|
158
|
+
opt :limit, :integer
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def call
|
|
162
|
+
User.where(status: osparams.status)
|
|
163
|
+
.limit(osparams.limit || 10)
|
|
164
|
+
end
|
|
165
|
+
end
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Using Schemacop v3 (recommended)
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
class FetchUsers < Inquery::Query
|
|
172
|
+
schema3 do
|
|
173
|
+
str! :status
|
|
174
|
+
int? :limit
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def call
|
|
178
|
+
User.where(status: osparams.status)
|
|
179
|
+
.limit(osparams.limit || 10)
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Configuring Default Schema Version
|
|
185
|
+
|
|
186
|
+
To use Schemacop v3 by default for all queries:
|
|
187
|
+
|
|
188
|
+
```ruby
|
|
189
|
+
# config/initializers/inquery.rb
|
|
190
|
+
Inquery.setup do |config|
|
|
191
|
+
config.default_schema_version = 3
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
# Now you can use 'schema' instead of 'schema3'
|
|
195
|
+
class FetchUsers < Inquery::Query
|
|
196
|
+
schema do
|
|
197
|
+
str! :status
|
|
198
|
+
int? :limit
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def call
|
|
202
|
+
User.where(status: osparams.status)
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
## Best Practices
|
|
208
|
+
|
|
209
|
+
### Query Organization
|
|
210
|
+
|
|
211
|
+
Organize queries by domain:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
app/queries/
|
|
215
|
+
├── user/
|
|
216
|
+
│ ├── fetch_active.rb
|
|
217
|
+
│ ├── fetch_by_email.rb
|
|
218
|
+
│ └── search.rb
|
|
219
|
+
├── order/
|
|
220
|
+
│ ├── fetch_recent.rb
|
|
221
|
+
│ └── fetch_by_status.rb
|
|
222
|
+
└── base_query.rb
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
### Testing
|
|
226
|
+
|
|
227
|
+
Test queries in isolation:
|
|
228
|
+
|
|
229
|
+
```ruby
|
|
230
|
+
# test/queries/fetch_active_users_test.rb
|
|
231
|
+
class FetchActiveUsersTest < ActiveSupport::TestCase
|
|
232
|
+
test 'returns only active users' do
|
|
233
|
+
active_user = create(:user, active: true)
|
|
234
|
+
inactive_user = create(:user, active: false)
|
|
235
|
+
|
|
236
|
+
result = FetchActiveUsers.run
|
|
237
|
+
|
|
238
|
+
assert_includes result, active_user
|
|
239
|
+
refute_includes result, inactive_user
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
### Naming Conventions
|
|
245
|
+
|
|
246
|
+
- Use descriptive names: `FetchActiveUsers`, not `Users`
|
|
247
|
+
- Prefix with verb: `Fetch`, `Create`, `Update`, `Delete`
|
|
248
|
+
- Organize in modules: `User::FetchActive`, `Order::FetchRecent`
|
|
249
|
+
|
|
250
|
+
### When to Use Query vs. Chainable
|
|
251
|
+
|
|
252
|
+
**Use `Inquery::Query` when:**
|
|
253
|
+
- Query doesn't need to be chained
|
|
254
|
+
- Result needs post-processing
|
|
255
|
+
- Query uses raw SQL
|
|
256
|
+
|
|
257
|
+
**Use `Inquery::Query::Chainable` when:**
|
|
258
|
+
- Query needs to be chainable
|
|
259
|
+
- Using as ActiveRecord scope
|
|
260
|
+
- Input and output are both relations
|
data/README.md
CHANGED
|
@@ -23,15 +23,21 @@ gem 'inquery'
|
|
|
23
23
|
|
|
24
24
|
## Compatibility
|
|
25
25
|
|
|
26
|
-
Inquery is tested
|
|
26
|
+
Inquery is tested against multiple Ruby and Rails version combinations. The following table shows the compatibility matrix:
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
| Ruby Version | Rails 5.2 | Rails 6.0 | Rails 6.1 | Rails 7.0 | Rails 7.1 | Rails 7.2 | Rails 8.0 | Rails 8.1 |
|
|
29
|
+
|--------------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|-----------|
|
|
30
|
+
| 2.6.2 | ✓ | ✓ | ✓ | - | - | - | - | - |
|
|
31
|
+
| 2.7.1 | - | ✓ | ✓ | ✓ | - | - | - | - |
|
|
32
|
+
| 3.0.1 | - | - | ✓ | ✓ | - | - | - | - |
|
|
33
|
+
| 3.1.0 | - | - | - | ✓ | ✓ | - | - | - |
|
|
34
|
+
| 3.2.0 | - | - | - | ✓ | ✓ | ✓ | - | - |
|
|
35
|
+
| 3.3.0 | - | - | - | ✓ | ✓ | ✓ | ✓ | ✓ |
|
|
36
|
+
| 3.4.1 | - | - | - | - | - | ✓ | ✓ | ✓ |
|
|
33
37
|
|
|
34
|
-
|
|
38
|
+
**Minimum supported versions:** Ruby 2.6.2 and Rails 5.2
|
|
39
|
+
|
|
40
|
+
Other Ruby/Rails version combinations might work but are not covered by our automated tests.
|
|
35
41
|
|
|
36
42
|
## Basic usage
|
|
37
43
|
|
|
@@ -353,4 +359,4 @@ post](http://craftingruby.com/posts/2015/06/29/query-objects-through-scopes.html
|
|
|
353
359
|
|
|
354
360
|
## Copyright
|
|
355
361
|
|
|
356
|
-
Copyright © 2016 -
|
|
362
|
+
Copyright © 2016 - 2026 Sitrox. See `LICENSE` for further details.
|
data/RUBY_VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
ruby-3.
|
|
1
|
+
ruby-3.3.5
|
data/Rakefile
CHANGED
|
@@ -3,6 +3,7 @@ task :gemspec do
|
|
|
3
3
|
spec.name = 'inquery'
|
|
4
4
|
spec.version = File.read('VERSION').chomp
|
|
5
5
|
spec.authors = ['Sitrox']
|
|
6
|
+
spec.homepage = 'https://github.com/sitrox/inquery'
|
|
6
7
|
spec.summary = %(
|
|
7
8
|
A skeleton that allows extracting queries into atomic, reusable classes.
|
|
8
9
|
)
|
|
@@ -11,17 +12,9 @@ task :gemspec do
|
|
|
11
12
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
12
13
|
spec.require_paths = ['lib']
|
|
13
14
|
|
|
14
|
-
spec.
|
|
15
|
-
spec.
|
|
16
|
-
spec.
|
|
17
|
-
spec.add_development_dependency 'haml'
|
|
18
|
-
spec.add_development_dependency 'yard'
|
|
19
|
-
spec.add_development_dependency 'rubocop', '1.25'
|
|
20
|
-
spec.add_development_dependency 'redcarpet'
|
|
21
|
-
spec.add_dependency 'minitest'
|
|
22
|
-
spec.add_dependency 'activesupport'
|
|
23
|
-
spec.add_dependency 'activerecord'
|
|
24
|
-
spec.add_dependency 'schemacop', '~> 3.0.8'
|
|
15
|
+
spec.add_dependency 'activesupport', '>= 5.1'
|
|
16
|
+
spec.add_dependency 'activerecord', '>= 5.1'
|
|
17
|
+
spec.add_dependency 'schemacop', '>= 3.0.8', '< 4.0'
|
|
25
18
|
end
|
|
26
19
|
|
|
27
20
|
File.write('inquery.gemspec', gemspec.to_ruby.strip)
|
data/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
1.0
|
|
1
|
+
1.1.0
|