concerns_on_rails 1.28.9 → 1.29.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f00644495f4a20c3265cfa9289708136b4bb086aebeeb16026ebd2c9e12f7991
|
|
4
|
+
data.tar.gz: 01162f76ade27fb2b42aa93c3317819fb4db96c761717fdc20cafeedd213046f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: fad1b9c385054e869d5dcd4012f1e06182b3597c63a500d6513521fbefd758480ffcaf85922c0d805a2d1b07430f03a3d0a3fb1184f510450adfabd311155630
|
|
7
|
+
data.tar.gz: e7a299357dc9f389a4e9e99241af15c783806a96dc4b9037fe5283d1737038b63f53224a3c6e77e5f5b0a926e3d341df435c8c7b0d319a73258b33a489a15614
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
<!-- CHANGELOG.md -->
|
|
2
2
|
|
|
3
|
+
## 1.29.0 (2026-09-21)
|
|
4
|
+
|
|
5
|
+
CI now runs **every Rails line the gemspec admits** — 6.0, 6.1, 7.0, 7.1, 7.2, 8.0 and 8.1 —
|
|
6
|
+
where it previously ran 7.0 through 8.0. Extending the matrix downwards found 201 failures
|
|
7
|
+
on the two new old lines and 0 on the new top line; all of them are fixed, and all seven
|
|
8
|
+
legs are green and blocking.
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
- **Rails 5.x is no longer declared.** The `actionpack` / `activerecord` / `activesupport`
|
|
12
|
+
floor moves from `>= 5.0` to `>= 6.0`. This drops nothing that ever worked: with
|
|
13
|
+
`required_ruby_version = ">= 3.2.0"`, the `>= 5.0` half was unreachable by construction —
|
|
14
|
+
Ruby 3's keyword-argument separation breaks Active Record 5.2's own `create_table`
|
|
15
|
+
(`schema_statements.rb:290`), so no bundle could satisfy both. Verified rather than
|
|
16
|
+
assumed: on Ruby 3.2 the suite fails 1,302 examples on Rails 5.2, every one of them
|
|
17
|
+
inside the framework.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
- **Controllers::Includable**: `?fields[table]=...` raised `LocalJumpError` ("no block
|
|
21
|
+
given") on Rails 6.0. `requested_fields` called the block-less `params[:fields].each_pair`
|
|
22
|
+
and chained `with_object`, but `ActionController::Parameters#each_pair` only began
|
|
23
|
+
returning an Enumerator in 6.1. It now iterates with a block, which behaves the same on
|
|
24
|
+
every line.
|
|
25
|
+
- **Models::Searchable**: the generated `search` scope raised
|
|
26
|
+
`ArgumentError: wrong number of arguments (given 2, expected 1)` for every call on Rails
|
|
27
|
+
6.0. Rails 6.0 forwards a scope's arguments through `define_method(name) { |*args| }`
|
|
28
|
+
with no `ruby2_keywords`, so under Ruby 3 the `ranked:` keyword reaches the body as a
|
|
29
|
+
trailing positional Hash. The scope now takes its options positionally and splats them
|
|
30
|
+
back out — same call signature, and an unknown key still raises.
|
|
31
|
+
|
|
32
|
+
### Documented
|
|
33
|
+
- Two features need a line newer than the 6.0 floor, and both now say so in the README's
|
|
34
|
+
compatibility table and in their own docs: `Controllers::Sortable`'s `nulls:` ordering
|
|
35
|
+
(Rails 6.1+, already raised at macro time) and `Models::Aliasable`'s **query side**
|
|
36
|
+
(Rails 6.1+ — resolving a `where`-hash key to an association, which is what makes Rails
|
|
37
|
+
alias the join, landed in 6.1; Aliasable's read/write side works on 6.0).
|
|
38
|
+
|
|
39
|
+
### Internal
|
|
40
|
+
- `gemfiles/rails_6.0.gemfile`, `rails_6.1.gemfile` and `rails_8.1.gemfile`; every gemfile
|
|
41
|
+
below 7.1 now pins `concurrent-ruby < 1.3.5`, which dropped its own `require "logger"`
|
|
42
|
+
that Active Support only started doing for itself in 7.1.
|
|
43
|
+
- The spec harness clears Active Record's schema cache and (on <= 6.1)
|
|
44
|
+
`ActiveSupport::Dependencies::Reference` between examples, gives anonymous spec models a
|
|
45
|
+
`model_name`, and gains a `min_rails:` metadata tag for examples whose feature is version
|
|
46
|
+
gated. Without the first two, specs that reuse table and model names across files saw the
|
|
47
|
+
PREVIOUS file's columns and classes on 6.0/6.1.
|
|
48
|
+
|
|
3
49
|
## 1.28.9 (2026-09-19)
|
|
4
50
|
|
|
5
51
|
CI now runs the matrix the gemspec actually claims: Rails 7.0–8.0 across Ruby 3.2/3.3/3.4,
|
data/README.md
CHANGED
|
@@ -11,7 +11,7 @@ One `include`, one declarative macro — done.
|
|
|
11
11
|
[](https://github.com/VSN2015/concerns_on_rails/actions/workflows/ci.yml)
|
|
12
12
|
[](https://vsn2015.github.io/concerns_on_rails)
|
|
13
13
|
[](https://www.ruby-lang.org)
|
|
14
|
-
[](https://rubyonrails.org)
|
|
15
15
|
[](#-license)
|
|
16
16
|
|
|
17
17
|
### [📖 **Documentation**](https://vsn2015.github.io/concerns_on_rails) · [💎 **RubyGems**](https://rubygems.org/gems/concerns_on_rails) · [📝 **Changelog**](CHANGELOG.md) · [🐛 **Issues**](https://github.com/VSN2015/concerns_on_rails/issues)
|
|
@@ -158,7 +158,7 @@ across all 43 concerns — press <kbd>/</kbd> and type.
|
|
|
158
158
|
Add to your application's `Gemfile`:
|
|
159
159
|
|
|
160
160
|
```ruby
|
|
161
|
-
gem "concerns_on_rails", "~> 1.
|
|
161
|
+
gem "concerns_on_rails", "~> 1.29"
|
|
162
162
|
```
|
|
163
163
|
|
|
164
164
|
Or pull the latest from GitHub:
|
|
@@ -200,7 +200,25 @@ still wins over the gem-wide fallback.
|
|
|
200
200
|
## 🧪 Compatibility
|
|
201
201
|
|
|
202
202
|
- **Ruby**: 3.2+
|
|
203
|
-
- **Rails**:
|
|
203
|
+
- **Rails**: 6.0 through 8.1
|
|
204
|
+
|
|
205
|
+
Every one of those lines runs the full suite on every push — Rails 6.0, 6.1, 7.0, 7.1, 7.2,
|
|
206
|
+
8.0 and 8.1 on SQLite, plus PostgreSQL and MySQL, and Ruby 3.3/3.4 against the current
|
|
207
|
+
lines. See [`.github/workflows/ci.yml`](.github/workflows/ci.yml).
|
|
208
|
+
|
|
209
|
+
**Rails 5.x is not supported**, despite what older versions of this gem declared. Rails 5
|
|
210
|
+
cannot run on any Ruby this gem supports: Ruby 3 separated keyword arguments, which breaks
|
|
211
|
+
Active Record 5.2's own `create_table`, and `required_ruby_version` here is `>= 3.2.0`. The
|
|
212
|
+
old `>= 5.0` dependency was therefore unreachable — no bundle could ever have satisfied
|
|
213
|
+
both halves of it.
|
|
214
|
+
|
|
215
|
+
Two things need a Rails line newer than the 6.0 floor. Both raise or are documented where
|
|
216
|
+
they apply, and nothing else in the gem is affected:
|
|
217
|
+
|
|
218
|
+
| Feature | Needs | Below that |
|
|
219
|
+
|---|---|---|
|
|
220
|
+
| `Controllers::Sortable` — `nulls:` ordering | Rails 6.1 | Raises `ArgumentError` at macro time (Arel gained the ordering nodes in 6.1) |
|
|
221
|
+
| `Models::Aliasable` — query side (`joins`/`where`/`eager_load` through an alias) | Rails 6.1 | Rails resolves a `where`-hash key to a table name, not an association, so the alias is not applied to the join. Readers, writers and `build_`/`create_` work on 6.0 |
|
|
204
222
|
|
|
205
223
|
---
|
|
206
224
|
|
|
@@ -765,7 +783,7 @@ User.find_by(email: User.normalize(:email, params[:email]))
|
|
|
765
783
|
- `with:` takes a preset, a Proc, or an Array of them (applied in order); every entry is validated at class load.
|
|
766
784
|
- `nil` values are skipped — no `nil → ""` coercion (use `:nullify_blank` for the opposite direction).
|
|
767
785
|
- Preset normalizers pass non-string values through unchanged.
|
|
768
|
-
- Works on Rails
|
|
786
|
+
- Works on Rails 6.0+ (no dependency on Rails 7.1's built-in `normalizes`).
|
|
769
787
|
|
|
770
788
|
---
|
|
771
789
|
|
|
@@ -1429,6 +1447,10 @@ unlike Publishable/Expirable/Activatable, this one has no validators gate.
|
|
|
1429
1447
|
|
|
1430
1448
|
## 🪞 Aliasable
|
|
1431
1449
|
|
|
1450
|
+
> **Rails 6.1+ for the query side.** `joins` / `where` / `eager_load` through an alias
|
|
1451
|
+
> needs Rails to resolve a `where`-hash key to an association, which landed in 6.1. The
|
|
1452
|
+
> read/write side (readers, writers, `build_`/`create_`, the ids pair) works on 6.0.
|
|
1453
|
+
|
|
1432
1454
|
Alias an existing association under a second name with **full** semantics — read, write/assign, build/create, and the query side (`joins` / `includes` / `where`-hash) — not just a delegated reader. (`alias_attribute` covers columns only; Rails has no built-in association aliasing.)
|
|
1433
1455
|
|
|
1434
1456
|
```ruby
|
|
@@ -2209,7 +2231,7 @@ When several rules apply to one request the `X-RateLimit-*` headers describe the
|
|
|
2209
2231
|
- The store MUST support **atomic increment-with-expiry** (`Rails.cache` with `#increment`, or Redis) — a non-atomic store under-counts under concurrency.
|
|
2210
2232
|
- There is **no in-process default store** on purpose: the first throttled request raises `ArgumentError` until you set `throttleable_store` (or the gem-wide fallback `ConcernsOnRails.setup { |c| c.cache_store = -> { Rails.cache } }`), so you never silently rate-limit per-process.
|
|
2211
2233
|
- When `Respondable` is included, the 429 body delegates to `render_error` (`code: "rate_limited"`).
|
|
2212
|
-
- Backports the essentials of Rails 7.2's `rate_limit` (with standardized headers) to Rails
|
|
2234
|
+
- Backports the essentials of Rails 7.2's `rate_limit` (with standardized headers) to Rails 6.0+. For richer rules (fail2ban, allow/deny lists, exponential backoff) reach for [`rack-attack`](https://github.com/rack/rack-attack).
|
|
2213
2235
|
|
|
2214
2236
|
---
|
|
2215
2237
|
|
|
@@ -2505,7 +2527,7 @@ Point your agent at `llms.txt` for an overview, or paste a single concern's `.md
|
|
|
2505
2527
|
bundle install # install dev dependencies
|
|
2506
2528
|
bundle exec rspec # run the test suite (1,830 examples)
|
|
2507
2529
|
gem build concerns_on_rails.gemspec # build the gem
|
|
2508
|
-
gem install ./concerns_on_rails-1.
|
|
2530
|
+
gem install ./concerns_on_rails-1.29.0.gem # install locally
|
|
2509
2531
|
|
|
2510
2532
|
# Preview the docs site locally (GitHub Pages serves docs/ as-is):
|
|
2511
2533
|
cd docs && python3 -m http.server 8000 # → http://localhost:8000
|
|
@@ -130,17 +130,22 @@ module ConcernsOnRails
|
|
|
130
130
|
return {} unless raw.respond_to?(:each_pair)
|
|
131
131
|
|
|
132
132
|
allowed = self.class.includable_fields
|
|
133
|
-
# Iterate via each_pair: in a real controller `raw` is an
|
|
133
|
+
# Iterate via each_pair WITH A BLOCK: in a real controller `raw` is an
|
|
134
134
|
# ActionController::Parameters, which has each_pair but no Enumerable —
|
|
135
135
|
# calling each_with_object directly on it was a guaranteed
|
|
136
|
-
# NoMethodError 500 for every ?fields[...]= request.
|
|
137
|
-
|
|
136
|
+
# NoMethodError 500 for every ?fields[...]= request. Its block-less
|
|
137
|
+
# form is no good either: Parameters#each_pair only started returning
|
|
138
|
+
# an Enumerator in Rails 6.1, so `raw.each_pair.with_object` raised
|
|
139
|
+
# LocalJumpError ("no block given") on 6.0.
|
|
140
|
+
memo = {}
|
|
141
|
+
raw.each_pair do |table, cols|
|
|
138
142
|
key = table.to_sym
|
|
139
143
|
next unless allowed.key?(key)
|
|
140
144
|
|
|
141
145
|
permitted = split_field_list(cols) & allowed[key]
|
|
142
146
|
memo[key] = permitted unless permitted.empty?
|
|
143
147
|
end
|
|
148
|
+
memo
|
|
144
149
|
end
|
|
145
150
|
|
|
146
151
|
private
|
|
@@ -46,6 +46,13 @@ module ConcernsOnRails
|
|
|
46
46
|
# must match the name you joined under (same rule as stock Rails):
|
|
47
47
|
# joins(:sections).where(sections: {...}) works,
|
|
48
48
|
# joins(:chapters).where(sections: {...}) does not.
|
|
49
|
+
# * THE QUERY SIDE NEEDS RAILS 6.1+. Resolving a where-hash key to an
|
|
50
|
+
# ASSOCIATION rather than to a literal table name landed in 6.1, and
|
|
51
|
+
# that resolution is what makes Rails alias the join to the
|
|
52
|
+
# reflection name. On 6.0 the same call emits
|
|
53
|
+
# INNER JOIN "chapters" ... WHERE "sections"... — a reference to an
|
|
54
|
+
# alias that was never created, which the database rejects. Readers,
|
|
55
|
+
# writers, build_/create_ and the ids pair all work on 6.0.
|
|
49
56
|
# * The belongs_to foreign-key attribute is NOT aliased — pair with
|
|
50
57
|
# Rails' alias_attribute (e.g. :writer_id, :author_id) if needed.
|
|
51
58
|
# * has_and_belongs_to_many cannot be aliased — use has_many :through.
|
|
@@ -74,7 +74,14 @@ module ConcernsOnRails
|
|
|
74
74
|
self.searchable_case_sensitive = case_sensitive
|
|
75
75
|
self.searchable_ranked = ranked
|
|
76
76
|
|
|
77
|
-
|
|
77
|
+
# Options are taken POSITIONALLY, not as keywords. Rails 6.0 forwards a
|
|
78
|
+
# scope's arguments through `define_method(name) { |*args| ... }` with no
|
|
79
|
+
# `ruby2_keywords`, so under Ruby 3 a `ranked:` keyword reaches the body as
|
|
80
|
+
# a trailing positional Hash and a kwarg-taking lambda dies with
|
|
81
|
+
# `wrong number of arguments (given 2, expected 1)`. Splatting an options
|
|
82
|
+
# hash back out here behaves identically on 6.0 through 8.1 — and still
|
|
83
|
+
# raises on an unknown key, because `search_relation` names its keywords.
|
|
84
|
+
scope :search, ->(query, opts = {}) { search_relation(query, **opts) }
|
|
78
85
|
end
|
|
79
86
|
|
|
80
87
|
# `ranked:` nil defers to the macro's setting; true/false override it.
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: concerns_on_rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.29.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ethan Nguyen
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-21 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: actionpack
|
|
@@ -16,7 +16,7 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: '
|
|
19
|
+
version: '6.0'
|
|
20
20
|
- - "<"
|
|
21
21
|
- !ruby/object:Gem::Version
|
|
22
22
|
version: '9'
|
|
@@ -26,7 +26,7 @@ dependencies:
|
|
|
26
26
|
requirements:
|
|
27
27
|
- - ">="
|
|
28
28
|
- !ruby/object:Gem::Version
|
|
29
|
-
version: '
|
|
29
|
+
version: '6.0'
|
|
30
30
|
- - "<"
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
32
|
version: '9'
|
|
@@ -36,7 +36,7 @@ dependencies:
|
|
|
36
36
|
requirements:
|
|
37
37
|
- - ">="
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: '
|
|
39
|
+
version: '6.0'
|
|
40
40
|
- - "<"
|
|
41
41
|
- !ruby/object:Gem::Version
|
|
42
42
|
version: '9'
|
|
@@ -46,7 +46,7 @@ dependencies:
|
|
|
46
46
|
requirements:
|
|
47
47
|
- - ">="
|
|
48
48
|
- !ruby/object:Gem::Version
|
|
49
|
-
version: '
|
|
49
|
+
version: '6.0'
|
|
50
50
|
- - "<"
|
|
51
51
|
- !ruby/object:Gem::Version
|
|
52
52
|
version: '9'
|
|
@@ -56,7 +56,7 @@ dependencies:
|
|
|
56
56
|
requirements:
|
|
57
57
|
- - ">="
|
|
58
58
|
- !ruby/object:Gem::Version
|
|
59
|
-
version: '
|
|
59
|
+
version: '6.0'
|
|
60
60
|
- - "<"
|
|
61
61
|
- !ruby/object:Gem::Version
|
|
62
62
|
version: '9'
|
|
@@ -66,7 +66,7 @@ dependencies:
|
|
|
66
66
|
requirements:
|
|
67
67
|
- - ">="
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
|
-
version: '
|
|
69
|
+
version: '6.0'
|
|
70
70
|
- - "<"
|
|
71
71
|
- !ruby/object:Gem::Version
|
|
72
72
|
version: '9'
|