active-query 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Appraisals +19 -0
- data/CHANGELOG.md +9 -1
- data/README.md +292 -100
- data/active-query.gemspec +46 -0
- data/gemfiles/rails_7_0.gemfile +9 -0
- data/gemfiles/rails_7_1.gemfile +9 -0
- data/gemfiles/rails_8_0.gemfile +9 -0
- data/lib/active-query.rb +3 -0
- data/lib/active_query/version.rb +1 -1
- data/lib/active_query.rb +1 -1
- metadata +36 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 426f4c764e93fcdacda7b354b9f4597ced451648ac4a0e56052f9cfc239f6d3f
|
|
4
|
+
data.tar.gz: b8e7db1ca8f99f4851a469feb412539c93a41e66f2d9d676ff619197dacf53a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 5437dc8c0c0e0ca61883a52799bc927c5bc710d708192be2fb1bd661c2f638e188d842be6098f3692d9fbd515a5659cdf881d684d49425ec9212e8d0b0d119b6
|
|
7
|
+
data.tar.gz: 7352b91b01bfa4fe0e96a9d6ad026f6a8ad6e1182d372e879c4eb0fdf453f2f410cd3f0016426b4a22ff9e42dd1f5cd6a45d21269340d20d89c87173142889f7
|
data/Appraisals
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
appraise 'rails-7.0' do
|
|
4
|
+
gem 'activerecord', '~> 7.0.0'
|
|
5
|
+
gem 'activesupport', '~> 7.0.0'
|
|
6
|
+
gem 'sqlite3', '~> 1.4'
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
appraise 'rails-7.1' do
|
|
10
|
+
gem 'activerecord', '~> 7.1.0'
|
|
11
|
+
gem 'activesupport', '~> 7.1.0'
|
|
12
|
+
gem 'sqlite3', '~> 1.4'
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
appraise 'rails-8.0' do
|
|
16
|
+
gem 'activerecord', '~> 8.0.0'
|
|
17
|
+
gem 'activesupport', '~> 8.0.0'
|
|
18
|
+
gem 'sqlite3', '~> 2.1'
|
|
19
|
+
end
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.1.3] - 2024-12-19
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
- Support for Rails 8.0
|
|
14
|
+
- Compatibility with SQLite3 version 2.1+ required by Rails 8
|
|
15
|
+
- Updated CI matrix to test against Rails 8.0
|
|
16
|
+
|
|
10
17
|
## [0.0.1] - 2024-12-19
|
|
11
18
|
|
|
12
19
|
### Added
|
|
@@ -31,5 +38,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
31
38
|
- **Resolvers**: Support complex query logic with resolver classes
|
|
32
39
|
- **Conditional Logic**: Apply scopes conditionally with `if`/`unless`
|
|
33
40
|
|
|
34
|
-
[Unreleased]: https://github.com/matiasasis/active-query/compare/v0.
|
|
41
|
+
[Unreleased]: https://github.com/matiasasis/active-query/compare/v0.1.3...HEAD
|
|
42
|
+
[0.1.3]: https://github.com/matiasasis/active-query/compare/v0.0.1...v0.1.3
|
|
35
43
|
[0.0.1]: https://github.com/matiasasis/active-query/releases/tag/v0.0.1
|
data/README.md
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
# ActiveQuery
|
|
2
2
|
|
|
3
|
-
ActiveQuery is a gem that helps you create query objects
|
|
3
|
+
ActiveQuery is a Ruby gem that helps you create clean, reusable query objects with a simple DSL. It provides type validation, conditional logic, and seamless ActiveRecord integration.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **Query
|
|
8
|
-
- **Type
|
|
9
|
-
- **
|
|
10
|
-
- **Operations**:
|
|
11
|
-
- **
|
|
7
|
+
- **Clean Query DSL**: Define queries with clear syntax and descriptions
|
|
8
|
+
- **Type Safety**: Built-in argument type validation (String, Integer, Float, Boolean)
|
|
9
|
+
- **Optional & Default Arguments**: Flexible argument handling
|
|
10
|
+
- **Custom Operations**: Extended query operations like `gt`, `lt`, `like`, etc.
|
|
11
|
+
- **Conditional Logic**: Apply scopes conditionally with `if` and `unless`
|
|
12
|
+
- **Resolver Pattern**: Support for complex query logic in separate classes
|
|
13
|
+
- **Custom Scopes**: Define reusable scopes within query objects
|
|
12
14
|
- **ActiveRecord Integration**: Works seamlessly with ActiveRecord models
|
|
13
15
|
|
|
14
16
|
## Installation
|
|
@@ -25,175 +27,365 @@ And then execute:
|
|
|
25
27
|
bundle install
|
|
26
28
|
```
|
|
27
29
|
|
|
28
|
-
Or install it yourself as:
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
gem install active-query
|
|
32
|
-
```
|
|
33
|
-
|
|
34
30
|
## Usage
|
|
35
31
|
|
|
36
32
|
### Basic Query Object
|
|
37
33
|
|
|
38
|
-
Create a query object by including `ActiveQuery::Base
|
|
34
|
+
Create a query object by including `ActiveQuery::Base` and defining queries with the `query` method:
|
|
39
35
|
|
|
40
36
|
```ruby
|
|
41
37
|
class UserQuery
|
|
42
38
|
include ActiveQuery::Base
|
|
43
|
-
|
|
39
|
+
|
|
44
40
|
# The model is automatically inferred from the class name (User)
|
|
45
|
-
# Or
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
query :
|
|
53
|
-
|
|
54
|
-
|
|
41
|
+
# Or explicitly set it:
|
|
42
|
+
model_name 'User'
|
|
43
|
+
|
|
44
|
+
# Simple query without arguments
|
|
45
|
+
query :active, 'Returns all active users', -> { scope.where(active: true) }
|
|
46
|
+
|
|
47
|
+
# Query with arguments and type validation
|
|
48
|
+
query :by_email, 'Find users by email address',
|
|
49
|
+
{ email: { type: String } },
|
|
50
|
+
-> (email:) { scope.where(email: email) }
|
|
55
51
|
end
|
|
56
52
|
```
|
|
57
53
|
|
|
58
54
|
### Using Query Objects
|
|
59
55
|
|
|
60
56
|
```ruby
|
|
61
|
-
#
|
|
62
|
-
users = UserQuery.by_email(email: 'john@example.com')
|
|
63
|
-
|
|
64
|
-
# Find active users
|
|
57
|
+
# Execute queries
|
|
65
58
|
active_users = UserQuery.active
|
|
59
|
+
user = UserQuery.by_email(email: 'john@example.com')
|
|
66
60
|
|
|
67
|
-
# Chain
|
|
68
|
-
|
|
61
|
+
# Chain with ActiveRecord methods
|
|
62
|
+
recent_active_users = UserQuery.active.where('created_at > ?', 1.week.ago)
|
|
69
63
|
```
|
|
70
64
|
|
|
71
|
-
###
|
|
65
|
+
### Argument Types and Validation
|
|
66
|
+
|
|
67
|
+
ActiveQuery supports several argument types with automatic validation:
|
|
72
68
|
|
|
73
69
|
```ruby
|
|
74
70
|
class ProductQuery
|
|
75
71
|
include ActiveQuery::Base
|
|
76
|
-
|
|
77
|
-
query :
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
72
|
+
|
|
73
|
+
query :filter_products, 'Filter products by various criteria',
|
|
74
|
+
{
|
|
75
|
+
name: { type: String },
|
|
76
|
+
price: { type: Float },
|
|
77
|
+
quantity: { type: Integer },
|
|
78
|
+
available: { type: Boolean }
|
|
79
|
+
},
|
|
80
|
+
-> (name:, price:, quantity:, available:) {
|
|
81
|
+
scope.where(name: name)
|
|
82
|
+
.where(price: price)
|
|
83
|
+
.where(quantity: quantity)
|
|
84
|
+
.where(available: available)
|
|
85
|
+
}
|
|
86
86
|
end
|
|
87
87
|
|
|
88
|
-
# Usage
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
# Usage with type validation
|
|
89
|
+
ProductQuery.filter_products(
|
|
90
|
+
name: 'Widget',
|
|
91
|
+
price: 19.99,
|
|
92
|
+
quantity: 10,
|
|
93
|
+
available: true
|
|
94
|
+
)
|
|
91
95
|
|
|
92
|
-
|
|
96
|
+
# This will raise ArgumentError due to type mismatch
|
|
97
|
+
ProductQuery.filter_products(name: 123, price: 'invalid', quantity: true, available: 'yes')
|
|
98
|
+
```
|
|
93
99
|
|
|
94
|
-
|
|
100
|
+
### Optional Arguments and Defaults
|
|
95
101
|
|
|
96
102
|
```ruby
|
|
97
103
|
class OrderQuery
|
|
98
104
|
include ActiveQuery::Base
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
105
|
+
|
|
106
|
+
query :search_orders, 'Search orders with optional filters',
|
|
107
|
+
{
|
|
108
|
+
status: { type: String },
|
|
109
|
+
paid: { type: Boolean, default: true },
|
|
110
|
+
customer_name: { type: String, optional: true }
|
|
111
|
+
},
|
|
112
|
+
-> (status:, paid:, customer_name:) {
|
|
113
|
+
scope.where(status: status)
|
|
114
|
+
.where(paid: paid)
|
|
115
|
+
.if(customer_name, -> { where('customer_name LIKE ?', "%#{customer_name}%") })
|
|
116
|
+
}
|
|
107
117
|
end
|
|
118
|
+
|
|
119
|
+
# Usage - customer_name is optional, paid defaults to true
|
|
120
|
+
OrderQuery.search_orders(status: 'pending')
|
|
121
|
+
OrderQuery.search_orders(status: 'completed', customer_name: 'John')
|
|
122
|
+
OrderQuery.search_orders(status: 'pending', paid: false, customer_name: 'Jane')
|
|
108
123
|
```
|
|
109
124
|
|
|
110
|
-
###
|
|
125
|
+
### Conditional Query Logic
|
|
111
126
|
|
|
112
|
-
|
|
127
|
+
Use `if` and `unless` methods for conditional query building:
|
|
113
128
|
|
|
114
129
|
```ruby
|
|
115
130
|
class UserQuery
|
|
116
131
|
include ActiveQuery::Base
|
|
117
|
-
|
|
118
|
-
query :
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
|
|
133
|
+
query :search_users, 'Search users with conditional filters',
|
|
134
|
+
{
|
|
135
|
+
name: { type: String, optional: true },
|
|
136
|
+
active: { type: Boolean, optional: true }
|
|
137
|
+
},
|
|
138
|
+
-> (name:, active:) {
|
|
139
|
+
scope.if(name.present?, -> { where('name LIKE ?', "%#{name}%") })
|
|
140
|
+
.if(active == true, -> { where(active: true) })
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
query :filter_unless_admin, 'Filter users unless they are admin',
|
|
144
|
+
{
|
|
145
|
+
role: { type: String, optional: true }
|
|
146
|
+
},
|
|
147
|
+
-> (role:) {
|
|
148
|
+
scope.unless(role == 'admin', -> { where.not(role: 'admin') })
|
|
149
|
+
}
|
|
150
|
+
end
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Extended Query Operations
|
|
154
|
+
|
|
155
|
+
ActiveQuery provides additional query operations beyond standard ActiveRecord:
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
class ProductQuery
|
|
159
|
+
include ActiveQuery::Base
|
|
160
|
+
|
|
161
|
+
# Comparison operations
|
|
162
|
+
query :expensive_products, 'Products above price threshold', -> { scope.gt(:price, 100) }
|
|
163
|
+
query :affordable_products, 'Products within budget', -> { scope.lteq(:price, 50) }
|
|
164
|
+
|
|
165
|
+
# Text search operations
|
|
166
|
+
query :search_by_name, 'Search products by name pattern', -> { scope.like(:name, 'Phone') }
|
|
167
|
+
query :products_starting_with, 'Products starting with prefix', -> { scope.start_like(:name, 'iPhone') }
|
|
168
|
+
query :products_ending_with, 'Products ending with suffix', -> { scope.end_like(:name, 'Pro') }
|
|
169
|
+
|
|
170
|
+
# Dynamic filtering
|
|
171
|
+
query :by_price_range, 'Filter by price range',
|
|
172
|
+
{ min_price: { type: Float }, max_price: { type: Float } },
|
|
173
|
+
-> (min_price:, max_price:) {
|
|
174
|
+
scope.gteq(:price, min_price)
|
|
175
|
+
.lteq(:price, max_price)
|
|
176
|
+
}
|
|
129
177
|
end
|
|
130
178
|
```
|
|
131
179
|
|
|
132
|
-
Available operations
|
|
180
|
+
**Available operations:**
|
|
133
181
|
- `gt(column, value)` - greater than
|
|
134
182
|
- `gteq(column, value)` - greater than or equal
|
|
135
|
-
- `lt(column, value)` - less than
|
|
183
|
+
- `lt(column, value)` - less than
|
|
136
184
|
- `lteq(column, value)` - less than or equal
|
|
137
|
-
- `like(column, value)` - contains pattern
|
|
185
|
+
- `like(column, value)` - contains pattern (wraps with %)
|
|
138
186
|
- `start_like(column, value)` - starts with pattern
|
|
139
187
|
- `end_like(column, value)` - ends with pattern
|
|
140
188
|
|
|
141
|
-
###
|
|
189
|
+
### Custom Scopes
|
|
142
190
|
|
|
143
|
-
|
|
191
|
+
Define reusable scopes within your query objects:
|
|
144
192
|
|
|
145
193
|
```ruby
|
|
194
|
+
class UserQuery
|
|
195
|
+
include ActiveQuery::Base
|
|
196
|
+
include ActiveQuery::Scopes
|
|
197
|
+
|
|
198
|
+
# Define custom scopes
|
|
199
|
+
module Scopes
|
|
200
|
+
include ActiveQuery::Scopes
|
|
201
|
+
|
|
202
|
+
scope :recent, -> { where('created_at > ?', 1.month.ago) }
|
|
203
|
+
scope :by_role, -> (role:) { where(role: role) }
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# Use scopes in queries
|
|
207
|
+
query :recent_admins, 'Find recent admin users', -> { scope.recent.by_role(role: 'admin') }
|
|
208
|
+
|
|
209
|
+
query :count_recent, 'Count recent users', -> { scope.recent.count }
|
|
210
|
+
end
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Resolver Pattern
|
|
214
|
+
|
|
215
|
+
For complex query logic, use the resolver pattern to keep your query objects clean:
|
|
216
|
+
|
|
217
|
+
```ruby
|
|
218
|
+
# Define a resolver
|
|
146
219
|
class UserStatsResolver < ActiveQuery::Resolver
|
|
147
|
-
def resolve(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
220
|
+
def resolve(min_orders: 5)
|
|
221
|
+
scope.joins(:orders)
|
|
222
|
+
.group('users.id')
|
|
223
|
+
.having('COUNT(orders.id) >= ?', min_orders)
|
|
224
|
+
.select('users.*, COUNT(orders.id) as order_count')
|
|
151
225
|
end
|
|
152
226
|
end
|
|
153
227
|
|
|
228
|
+
# Use resolver in query object
|
|
154
229
|
class UserQuery
|
|
155
230
|
include ActiveQuery::Base
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
231
|
+
|
|
232
|
+
# Resolver without arguments
|
|
233
|
+
query :high_value_users, 'Users with many orders',
|
|
234
|
+
resolver: UserStatsResolver
|
|
235
|
+
|
|
236
|
+
# Resolver with arguments
|
|
237
|
+
query :users_with_orders, 'Users with minimum order count',
|
|
238
|
+
{ min_orders: { type: Integer } },
|
|
239
|
+
resolver: UserStatsResolver
|
|
160
240
|
end
|
|
161
241
|
|
|
162
242
|
# Usage
|
|
163
|
-
|
|
243
|
+
UserQuery.high_value_users
|
|
244
|
+
UserQuery.users_with_orders(min_orders: 10)
|
|
164
245
|
```
|
|
165
246
|
|
|
166
|
-
###
|
|
247
|
+
### Query Introspection
|
|
167
248
|
|
|
168
|
-
|
|
249
|
+
Query objects provide metadata about available queries:
|
|
169
250
|
|
|
170
251
|
```ruby
|
|
171
|
-
class
|
|
252
|
+
class UserQuery
|
|
172
253
|
include ActiveQuery::Base
|
|
173
|
-
|
|
174
|
-
query :
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
254
|
+
|
|
255
|
+
query :active, 'Find active users', -> { scope.where(active: true) }
|
|
256
|
+
query :by_name, 'Find by name', { name: { type: String } }, -> (name:) { scope.where(name: name) }
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Get all available queries
|
|
260
|
+
UserQuery.queries
|
|
261
|
+
# => [
|
|
262
|
+
# { name: :active, description: "Find active users", args_def: {} },
|
|
263
|
+
# { name: :by_name, description: "Find by name", args_def: { name: { type: String } } }
|
|
264
|
+
# ]
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Error Handling
|
|
268
|
+
|
|
269
|
+
ActiveQuery provides clear error messages for common mistakes:
|
|
270
|
+
|
|
271
|
+
```ruby
|
|
272
|
+
# Missing required arguments
|
|
273
|
+
UserQuery.by_email
|
|
274
|
+
# => ArgumentError: Params missing: [:email]
|
|
275
|
+
|
|
276
|
+
# Wrong argument type
|
|
277
|
+
UserQuery.by_email(email: 123)
|
|
278
|
+
# => ArgumentError: :email must be of type String
|
|
279
|
+
|
|
280
|
+
# Unknown arguments
|
|
281
|
+
UserQuery.by_email(email: 'test@example.com', invalid_param: 'value')
|
|
282
|
+
# => ArgumentError: Unknown params: [:invalid_param]
|
|
283
|
+
|
|
284
|
+
# Optional and default together (validation error)
|
|
285
|
+
query :invalid_query, 'This will fail',
|
|
286
|
+
{ param: { type: String, optional: true, default: 'value' } },
|
|
287
|
+
-> (param:) { scope }
|
|
288
|
+
# => ArgumentError: Optional and Default params can't be present together: [:param]
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Integration with Rails
|
|
292
|
+
|
|
293
|
+
ActiveQuery works seamlessly with Rails applications:
|
|
294
|
+
|
|
295
|
+
```ruby
|
|
296
|
+
# app/queries/user_query.rb
|
|
297
|
+
class UserQuery
|
|
298
|
+
include ActiveQuery::Base
|
|
299
|
+
|
|
300
|
+
query :active, 'Active users', -> { scope.where(active: true) }
|
|
301
|
+
query :by_role, 'Users by role', { role: { type: String } }, -> (role:) { scope.where(role: role) }
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
# In controllers
|
|
305
|
+
class UsersController < ApplicationController
|
|
306
|
+
def index
|
|
307
|
+
@users = UserQuery.active
|
|
308
|
+
end
|
|
309
|
+
|
|
310
|
+
def admins
|
|
311
|
+
@admins = UserQuery.by_role(role: 'admin')
|
|
182
312
|
end
|
|
183
313
|
end
|
|
314
|
+
|
|
315
|
+
# In views or anywhere else
|
|
316
|
+
<%= UserQuery.active.count %> active users
|
|
184
317
|
```
|
|
185
318
|
|
|
186
319
|
## Requirements
|
|
187
320
|
|
|
188
|
-
- Ruby >= 2.
|
|
189
|
-
- ActiveRecord >= 6.1
|
|
190
|
-
- ActiveSupport >= 6.1
|
|
321
|
+
- Ruby >= 3.2.0
|
|
322
|
+
- ActiveRecord >= 6.1, < 9.0
|
|
323
|
+
- ActiveSupport >= 6.1, < 9.0
|
|
324
|
+
|
|
325
|
+
### Rails 8 Support
|
|
326
|
+
|
|
327
|
+
ActiveQuery fully supports Rails 8.0! Note that Rails 8 requires SQLite3 version 2.1 or higher:
|
|
328
|
+
|
|
329
|
+
```ruby
|
|
330
|
+
# For Rails 8 applications
|
|
331
|
+
gem 'sqlite3', '~> 2.1'
|
|
332
|
+
|
|
333
|
+
# For Rails 7 and below
|
|
334
|
+
gem 'sqlite3', '~> 1.4'
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
See [RAILS_8_MIGRATION.md](RAILS_8_MIGRATION.md) for detailed migration instructions.
|
|
191
338
|
|
|
192
339
|
## Development
|
|
193
340
|
|
|
194
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt
|
|
341
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt.
|
|
342
|
+
|
|
343
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`.
|
|
344
|
+
|
|
345
|
+
### Testing Against Multiple Rails Versions
|
|
346
|
+
|
|
347
|
+
This gem is tested against Rails 7.0, 7.1, and 8.0 to ensure compatibility across versions.
|
|
348
|
+
|
|
349
|
+
#### Running Tests Locally
|
|
350
|
+
|
|
351
|
+
To test against all supported Rails versions locally:
|
|
352
|
+
|
|
353
|
+
```bash
|
|
354
|
+
# Test against all Rails versions
|
|
355
|
+
./bin/test_all_rails
|
|
356
|
+
|
|
357
|
+
# Test against a specific Rails version
|
|
358
|
+
BUNDLE_GEMFILE=gemfiles/rails_7_0.gemfile bundle exec rake spec
|
|
359
|
+
BUNDLE_GEMFILE=gemfiles/rails_7_1.gemfile bundle exec rake spec
|
|
360
|
+
BUNDLE_GEMFILE=gemfiles/rails_8_0.gemfile bundle exec rake spec
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### Using Appraisal (Alternative Method)
|
|
364
|
+
|
|
365
|
+
If you prefer using the `appraisal` gem:
|
|
366
|
+
|
|
367
|
+
```bash
|
|
368
|
+
# Install appraisal gemfiles
|
|
369
|
+
bundle exec appraisal install
|
|
370
|
+
|
|
371
|
+
# Run tests against all Rails versions
|
|
372
|
+
bundle exec appraisal rake spec
|
|
373
|
+
|
|
374
|
+
# Run tests against specific Rails version
|
|
375
|
+
bundle exec appraisal rails-7-0 rake spec
|
|
376
|
+
bundle exec appraisal rails-7-1 rake spec
|
|
377
|
+
bundle exec appraisal rails-8-0 rake spec
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
#### Continuous Integration
|
|
381
|
+
|
|
382
|
+
The gem uses GitHub Actions to automatically test against multiple Ruby and Rails versions in a matrix configuration. Each push and pull request triggers tests across:
|
|
383
|
+
|
|
384
|
+
- Ruby versions: 3.2, 3.3
|
|
385
|
+
- Rails versions: 7.0, 7.1, 8.0
|
|
386
|
+
- Appropriate SQLite3 versions for each Rails version (1.4 for Rails 7.x, 2.1+ for Rails 8.0)
|
|
195
387
|
|
|
196
|
-
|
|
388
|
+
See `.github/workflows/main.yml` for the complete CI configuration.
|
|
197
389
|
|
|
198
390
|
## Contributing
|
|
199
391
|
|
|
@@ -205,4 +397,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
|
205
397
|
|
|
206
398
|
## Code of Conduct
|
|
207
399
|
|
|
208
|
-
Everyone interacting in the ActiveQuery project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/matiasasis/active-query/blob/master/CODE_OF_CONDUCT.md).
|
|
400
|
+
Everyone interacting in the ActiveQuery project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/matiasasis/active-query/blob/master/CODE_OF_CONDUCT.md).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "lib/active_query/version"
|
|
4
|
+
|
|
5
|
+
Gem::Specification.new do |spec|
|
|
6
|
+
spec.name = "active-query"
|
|
7
|
+
spec.version = ActiveQuery::VERSION
|
|
8
|
+
spec.authors = ["Matias Asis"]
|
|
9
|
+
spec.email = ["matiasis.90@gmail.com"]
|
|
10
|
+
|
|
11
|
+
spec.summary = "ActiveQuery is a gem that helps you to create query objects in a simple way."
|
|
12
|
+
spec.description = "ActiveQuery is a gem that helps you to create query objects in a simple way. It provides a DSL to define queries and scopes for your query object."
|
|
13
|
+
spec.homepage = "https://github.com/matiasasis/active-query"
|
|
14
|
+
spec.license = "MIT"
|
|
15
|
+
spec.required_ruby_version = ">= 3.2.0"
|
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/matiasasis/active-query"
|
|
18
|
+
spec.metadata["bug_tracker_uri"] = "https://github.com/matiasasis/active-query/issues"
|
|
19
|
+
spec.metadata["changelog_uri"] = "https://github.com/matiasasis/active-query/blob/master/CHANGELOG.md"
|
|
20
|
+
|
|
21
|
+
# Specify which files should be added to the gem when it is released.
|
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
23
|
+
spec.files = Dir.chdir(__dir__) do
|
|
24
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
|
25
|
+
(File.expand_path(f) == __FILE__) ||
|
|
26
|
+
f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile]) ||
|
|
27
|
+
f.match?(/\.gem\z/)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
spec.bindir = "exe"
|
|
31
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
|
32
|
+
spec.require_paths = ['lib']
|
|
33
|
+
|
|
34
|
+
# Dependencies
|
|
35
|
+
spec.add_dependency 'activerecord', '>= 6.1', '< 9.0'
|
|
36
|
+
spec.add_dependency 'activesupport', '>= 6.1', '< 9.0'
|
|
37
|
+
|
|
38
|
+
# Dev dependencies
|
|
39
|
+
spec.add_development_dependency 'rake', '~> 13.0'
|
|
40
|
+
spec.add_development_dependency 'rspec', '~> 3.9.0'
|
|
41
|
+
spec.add_development_dependency 'simplecov', '~> 0.17.1'
|
|
42
|
+
spec.add_development_dependency 'sqlite3', '>= 1.5.1', '< 3.0'
|
|
43
|
+
spec.add_development_dependency 'database_cleaner-active_record', '~> 2.2.0'
|
|
44
|
+
spec.add_development_dependency 'byebug', '~> 11.0'
|
|
45
|
+
spec.add_development_dependency 'appraisal', '~> 2.4'
|
|
46
|
+
end
|
data/lib/active-query.rb
ADDED
data/lib/active_query/version.rb
CHANGED
data/lib/active_query.rb
CHANGED
|
@@ -84,7 +84,7 @@ module ActiveQuery
|
|
|
84
84
|
def query_with_arguments(name, description, args_def, lambda)
|
|
85
85
|
register_query(name, description, args_def)
|
|
86
86
|
|
|
87
|
-
define_singleton_method(name) do |given_args|
|
|
87
|
+
define_singleton_method(name) do |given_args = {}|
|
|
88
88
|
given_args = validate_args(name, given_args, args_def)
|
|
89
89
|
lambda.call(**given_args)
|
|
90
90
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: active-query
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matias Asis
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: exe
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
13
|
name: activerecord
|
|
@@ -19,7 +18,7 @@ dependencies:
|
|
|
19
18
|
version: '6.1'
|
|
20
19
|
- - "<"
|
|
21
20
|
- !ruby/object:Gem::Version
|
|
22
|
-
version: '
|
|
21
|
+
version: '9.0'
|
|
23
22
|
type: :runtime
|
|
24
23
|
prerelease: false
|
|
25
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -29,7 +28,7 @@ dependencies:
|
|
|
29
28
|
version: '6.1'
|
|
30
29
|
- - "<"
|
|
31
30
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: '
|
|
31
|
+
version: '9.0'
|
|
33
32
|
- !ruby/object:Gem::Dependency
|
|
34
33
|
name: activesupport
|
|
35
34
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -39,7 +38,7 @@ dependencies:
|
|
|
39
38
|
version: '6.1'
|
|
40
39
|
- - "<"
|
|
41
40
|
- !ruby/object:Gem::Version
|
|
42
|
-
version: '
|
|
41
|
+
version: '9.0'
|
|
43
42
|
type: :runtime
|
|
44
43
|
prerelease: false
|
|
45
44
|
version_requirements: !ruby/object:Gem::Requirement
|
|
@@ -49,7 +48,7 @@ dependencies:
|
|
|
49
48
|
version: '6.1'
|
|
50
49
|
- - "<"
|
|
51
50
|
- !ruby/object:Gem::Version
|
|
52
|
-
version: '
|
|
51
|
+
version: '9.0'
|
|
53
52
|
- !ruby/object:Gem::Dependency
|
|
54
53
|
name: rake
|
|
55
54
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -96,16 +95,22 @@ dependencies:
|
|
|
96
95
|
name: sqlite3
|
|
97
96
|
requirement: !ruby/object:Gem::Requirement
|
|
98
97
|
requirements:
|
|
99
|
-
- - "
|
|
98
|
+
- - ">="
|
|
100
99
|
- !ruby/object:Gem::Version
|
|
101
100
|
version: 1.5.1
|
|
101
|
+
- - "<"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: '3.0'
|
|
102
104
|
type: :development
|
|
103
105
|
prerelease: false
|
|
104
106
|
version_requirements: !ruby/object:Gem::Requirement
|
|
105
107
|
requirements:
|
|
106
|
-
- - "
|
|
108
|
+
- - ">="
|
|
107
109
|
- !ruby/object:Gem::Version
|
|
108
110
|
version: 1.5.1
|
|
111
|
+
- - "<"
|
|
112
|
+
- !ruby/object:Gem::Version
|
|
113
|
+
version: '3.0'
|
|
109
114
|
- !ruby/object:Gem::Dependency
|
|
110
115
|
name: database_cleaner-active_record
|
|
111
116
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -134,6 +139,20 @@ dependencies:
|
|
|
134
139
|
- - "~>"
|
|
135
140
|
- !ruby/object:Gem::Version
|
|
136
141
|
version: '11.0'
|
|
142
|
+
- !ruby/object:Gem::Dependency
|
|
143
|
+
name: appraisal
|
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
|
145
|
+
requirements:
|
|
146
|
+
- - "~>"
|
|
147
|
+
- !ruby/object:Gem::Version
|
|
148
|
+
version: '2.4'
|
|
149
|
+
type: :development
|
|
150
|
+
prerelease: false
|
|
151
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
152
|
+
requirements:
|
|
153
|
+
- - "~>"
|
|
154
|
+
- !ruby/object:Gem::Version
|
|
155
|
+
version: '2.4'
|
|
137
156
|
description: ActiveQuery is a gem that helps you to create query objects in a simple
|
|
138
157
|
way. It provides a DSL to define queries and scopes for your query object.
|
|
139
158
|
email:
|
|
@@ -145,12 +164,18 @@ extra_rdoc_files: []
|
|
|
145
164
|
files:
|
|
146
165
|
- ".byebug_history"
|
|
147
166
|
- ".rspec"
|
|
167
|
+
- Appraisals
|
|
148
168
|
- CHANGELOG.md
|
|
149
169
|
- CODE_OF_CONDUCT.md
|
|
150
170
|
- LICENSE.txt
|
|
151
171
|
- README.md
|
|
152
172
|
- Rakefile
|
|
173
|
+
- active-query.gemspec
|
|
153
174
|
- exe/active-query
|
|
175
|
+
- gemfiles/rails_7_0.gemfile
|
|
176
|
+
- gemfiles/rails_7_1.gemfile
|
|
177
|
+
- gemfiles/rails_8_0.gemfile
|
|
178
|
+
- lib/active-query.rb
|
|
154
179
|
- lib/active_query.rb
|
|
155
180
|
- lib/active_query/resolver.rb
|
|
156
181
|
- lib/active_query/version.rb
|
|
@@ -164,7 +189,6 @@ metadata:
|
|
|
164
189
|
bug_tracker_uri: https://github.com/matiasasis/active-query/issues
|
|
165
190
|
changelog_uri: https://github.com/matiasasis/active-query/blob/master/CHANGELOG.md
|
|
166
191
|
rubygems_mfa_required: 'true'
|
|
167
|
-
post_install_message:
|
|
168
192
|
rdoc_options: []
|
|
169
193
|
require_paths:
|
|
170
194
|
- lib
|
|
@@ -172,15 +196,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
172
196
|
requirements:
|
|
173
197
|
- - ">="
|
|
174
198
|
- !ruby/object:Gem::Version
|
|
175
|
-
version: 2.
|
|
199
|
+
version: 3.2.0
|
|
176
200
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
201
|
requirements:
|
|
178
202
|
- - ">="
|
|
179
203
|
- !ruby/object:Gem::Version
|
|
180
204
|
version: '0'
|
|
181
205
|
requirements: []
|
|
182
|
-
rubygems_version:
|
|
183
|
-
signing_key:
|
|
206
|
+
rubygems_version: 4.0.2
|
|
184
207
|
specification_version: 4
|
|
185
208
|
summary: ActiveQuery is a gem that helps you to create query objects in a simple way.
|
|
186
209
|
test_files: []
|