activerecord-minimizer 0.1.1 → 0.1.2
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/CHANGELOG.md +14 -0
- data/README.md +15 -5
- data/lib/ar_minimizer/slim.rb +50 -12
- data/lib/ar_minimizer/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 765a2a713e6c6e2582ea3710affccdbfcae87fc798c40a8687f32856b24d2d6b
|
|
4
|
+
data.tar.gz: 32d4267611a306b162b1a3c47d082c29b6a080d30ae066d3dfd1a6db1d4a69a7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 67faf17cd90cfd3583be2eefbc532423e75628270a198f1f55834c2881b62c3428db9c83b272e6ccfb4ffd5d1ecfe8f0233b8b2ce14cbc9f4a2671458d5cb923
|
|
7
|
+
data.tar.gz: 8b9fafd7a79f04d9dda376491def78b8441003e9b948955c8a7e07d7a3bf06669842bdb7b3f2922509ec54932f580fe79110ac3779ca4be01cb3fdb090fffb83
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.2 (2026-10-18)
|
|
4
|
+
|
|
5
|
+
- Strict mode no longer breaks what gems and Rails call by name, so a keep
|
|
6
|
+
list is only needed for an app's own names:
|
|
7
|
+
- `<attr>_in_database` and `clear_<attr>_change` are generated on first
|
|
8
|
+
call: `increment!`/`decrement!`, and so counter caches, raised before.
|
|
9
|
+
- Devise models keep every attribute method of the columns Devise uses
|
|
10
|
+
(email, encrypted_password, unconfirmed_email and the configured keys).
|
|
11
|
+
Recoverable asks `respond_to?("will_save_change_to_<key>?")` before
|
|
12
|
+
clearing the reset password token, so without these an old reset link
|
|
13
|
+
kept working after a password change.
|
|
14
|
+
- Active Storage blobs and Action Mailbox inbound emails keep the methods
|
|
15
|
+
those frameworks call.
|
|
16
|
+
|
|
3
17
|
## 0.1.1 (2026-10-18)
|
|
4
18
|
|
|
5
19
|
- Small records work on Rails main, whose attribute sets take a `default_keys` argument and get a fresh `{}` from Rails; the association cache Rails main leaves `nil` until used is left alone.
|
data/README.md
CHANGED
|
@@ -26,18 +26,25 @@ name_changed? was removed by activerecord-minimizer's strict mode; use attribute
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
[rubocop-minify](../rubocop-minify) rewrites those calls in your Ruby and ERB.
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
To find what to put there, run the test suite with `strict = false` and
|
|
29
|
+
What other gems and your own code call by name goes in a keep list,
|
|
30
|
+
`config/ar_minimizer_keep.txt`, one `name` or `Model#name` per line. To find
|
|
31
|
+
what to put there, run the test suite with `strict = false` and
|
|
33
32
|
`AR_MINIMIZER_PROFILE=tmp/ar_minimizer`, then `bin/rails ar_minimizer:profile`.
|
|
34
33
|
|
|
35
|
-
Rails
|
|
34
|
+
Rails and common gems still get what they call by name, without a keep list:
|
|
36
35
|
|
|
37
36
|
* `<attr>_before_type_cast` and `<attr>_came_from_user?` answer `respond_to?`
|
|
38
37
|
and are generated on first call. Form fields and numericality validation ask
|
|
39
38
|
before calling them, and quietly do something else when told no (a form
|
|
40
39
|
would show the cast value, `"abc"` would validate as 0).
|
|
40
|
+
* `<attr>_in_database` and `clear_<attr>_change` are generated on first call:
|
|
41
|
+
`increment!`/`decrement!`, and so counter caches, use them.
|
|
42
|
+
* Devise models keep every attribute method of the columns Devise uses (email,
|
|
43
|
+
encrypted_password, unconfirmed_email and the configured keys). Recoverable
|
|
44
|
+
asks `respond_to?` before clearing the reset password token on a password
|
|
45
|
+
or email change.
|
|
46
|
+
* Active Storage blobs and Action Mailbox inbound emails keep what those
|
|
47
|
+
frameworks call (`service_name_changed?`, `status_previously_changed?`, ...).
|
|
41
48
|
* `<enum>_for_database` and `updated_at_before_type_cast`/`_came_from_user?`
|
|
42
49
|
are generated up front: Rails calls them on hot paths.
|
|
43
50
|
* Aliases (`alias_attribute`, Rails' own `id_value`), partial selects
|
|
@@ -47,6 +54,9 @@ Rails itself still gets what it needs:
|
|
|
47
54
|
`config.ar_minimizer.strict = false` keeps the removed methods working: the
|
|
48
55
|
first call to one generates it on that model.
|
|
49
56
|
|
|
57
|
+
Turn `slim` on in development and tests as well as production: the
|
|
58
|
+
errors then show up while you work and in CI. Slim follows code reloads.
|
|
59
|
+
|
|
50
60
|
## Compiling call sites
|
|
51
61
|
|
|
52
62
|
Calls whose receiver is known to be a record of a model with that column are
|
data/lib/ar_minimizer/slim.rb
CHANGED
|
@@ -17,11 +17,35 @@ module ArMinimizer
|
|
|
17
17
|
|
|
18
18
|
MATCH = ActiveModel::AttributeMethods::ClassMethods::AttributeMethodPattern::AttributeMethod
|
|
19
19
|
|
|
20
|
-
#
|
|
21
|
-
#
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
|
|
20
|
+
# [prefix, suffix, proxy] of the patterns Rails itself calls by name, for
|
|
21
|
+
# any attribute. Strict mode generates them on first call instead of
|
|
22
|
+
# removing them:
|
|
23
|
+
# - _before_type_cast, _came_from_user?: Rails asks respond_to? first and
|
|
24
|
+
# quietly does something else when told no (form fields would show the
|
|
25
|
+
# cast value, numericality would validate it: "abc" -> 0).
|
|
26
|
+
# - _in_database, clear_..._change: increment!/decrement!, and so every
|
|
27
|
+
# counter cache, call them on the attribute they change.
|
|
28
|
+
ON_DEMAND = [
|
|
29
|
+
["", "_before_type_cast", "attribute_before_type_cast"],
|
|
30
|
+
["", "_came_from_user?", "attribute_came_from_user?"],
|
|
31
|
+
["", "_in_database", "attribute_in_database"],
|
|
32
|
+
["clear_", "_change", "clear_attribute_change"],
|
|
33
|
+
].freeze
|
|
34
|
+
ON_DEMAND_PROXIES = ON_DEMAND.map(&:last).freeze
|
|
35
|
+
|
|
36
|
+
# Methods Rails' own models call by name.
|
|
37
|
+
FRAMEWORK_KEEP = {
|
|
38
|
+
"ActiveStorage::Blob" => %w[content_type_previously_changed? metadata_previously_changed? metadata_changed? service_name_changed?],
|
|
39
|
+
"ActionMailbox::InboundEmail" => %w[status_previously_changed?],
|
|
40
|
+
}.freeze
|
|
41
|
+
|
|
42
|
+
# Columns Devise works with on a model, besides its configured keys: it
|
|
43
|
+
# calls their dirty-tracking methods by name, some behind respond_to?
|
|
44
|
+
# (Recoverable clears the reset password token only when it's told the
|
|
45
|
+
# password or an authentication key will change).
|
|
46
|
+
DEVISE_COLUMNS = %w[email encrypted_password unconfirmed_email].freeze
|
|
47
|
+
DEVISE_KEYS = %i[authentication_keys reset_password_keys confirmation_keys unlock_keys
|
|
48
|
+
case_insensitive_keys strip_whitespace_keys].freeze
|
|
25
49
|
|
|
26
50
|
class << self
|
|
27
51
|
attr_reader :keep, :keep_methods
|
|
@@ -86,6 +110,7 @@ module ArMinimizer
|
|
|
86
110
|
return false if Thread.current[:ar_minimizer_generating] == name
|
|
87
111
|
return false if keep.include?(pattern.proxy_target)
|
|
88
112
|
return false if keep_methods.include?(name) || keep_methods.include?("#{model.name}##{name}")
|
|
113
|
+
return false if FRAMEWORK_KEEP[model.name]&.include?(name)
|
|
89
114
|
|
|
90
115
|
!framework_calls?(model, pattern.proxy_target, attr_name.to_s)
|
|
91
116
|
end
|
|
@@ -145,8 +170,21 @@ module ArMinimizer
|
|
|
145
170
|
# every enum predicate (`published?`) and enum scope calls status_for_database
|
|
146
171
|
when "attribute_for_database" then model.defined_enums.key?(attr)
|
|
147
172
|
# cache_version, on every cache key with recyclable cache keys
|
|
148
|
-
when "attribute_before_type_cast", "attribute_came_from_user?" then attr == "updated_at"
|
|
149
|
-
else
|
|
173
|
+
when "attribute_before_type_cast", "attribute_came_from_user?" then attr == "updated_at" || devise_column?(model, attr)
|
|
174
|
+
else devise_column?(model, attr)
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# All of a Devise model's attribute methods for the columns Devise uses.
|
|
179
|
+
def devise_column?(model, attr)
|
|
180
|
+
return false unless model.respond_to?(:devise_modules)
|
|
181
|
+
return true if DEVISE_COLUMNS.include?(attr)
|
|
182
|
+
|
|
183
|
+
DEVISE_KEYS.any? do |config|
|
|
184
|
+
next false unless model.respond_to?(config)
|
|
185
|
+
|
|
186
|
+
keys = model.public_send(config)
|
|
187
|
+
(keys.is_a?(Hash) ? keys.keys : Array(keys)).any? { it.to_s == attr }
|
|
150
188
|
end
|
|
151
189
|
end
|
|
152
190
|
end
|
|
@@ -190,7 +228,7 @@ module ArMinimizer
|
|
|
190
228
|
# without this `user.method(:name_changed?)` raises NameError.
|
|
191
229
|
def respond_to_missing?(name, include_private = false)
|
|
192
230
|
# Strict: matched_attribute_method only matches readers, writers and
|
|
193
|
-
# the
|
|
231
|
+
# the ON_DEMAND patterns.
|
|
194
232
|
super || (Slim.enabled? && !matched_attribute_method(name.to_s).nil?)
|
|
195
233
|
end
|
|
196
234
|
|
|
@@ -209,7 +247,7 @@ module ArMinimizer
|
|
|
209
247
|
return super
|
|
210
248
|
end
|
|
211
249
|
|
|
212
|
-
Slim.generate(self.class, name.name, match) if Slim.lazy? || Slim::
|
|
250
|
+
Slim.generate(self.class, name.name, match) if Slim.lazy? || Slim::ON_DEMAND_PROXIES.include?(match.proxy_target)
|
|
213
251
|
attribute_missing(match, ...)
|
|
214
252
|
end
|
|
215
253
|
|
|
@@ -219,10 +257,10 @@ module ArMinimizer
|
|
|
219
257
|
def matched_attribute_method(method_name)
|
|
220
258
|
return super unless Slim.strict?
|
|
221
259
|
|
|
222
|
-
Slim::
|
|
223
|
-
next unless method_name.end_with?(suffix)
|
|
260
|
+
Slim::ON_DEMAND.each do |prefix, suffix, proxy|
|
|
261
|
+
next unless method_name.length > prefix.length + suffix.length && method_name.start_with?(prefix) && method_name.end_with?(suffix)
|
|
224
262
|
|
|
225
|
-
attr = method_name.
|
|
263
|
+
attr = method_name[prefix.length...-suffix.length]
|
|
226
264
|
klass = self.class
|
|
227
265
|
return Slim::MATCH.new(proxy, attr) if klass._has_attribute?(attr) || klass.attribute_aliases.key?(attr) || @attributes&.key?(attr)
|
|
228
266
|
end
|
data/lib/ar_minimizer/version.rb
CHANGED