glib-web 5.0.9 → 5.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/app/models/concerns/glib/enum_symbolization.rb +65 -11
- metadata +7 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9af6a7a8e8f3cd4b9a45446e58347ff9ecc2130d1ce4f715da68ead1c7646ab5
|
|
4
|
+
data.tar.gz: 3239c38d6b96f609eb961d5e427121bee47804430475bc0fe0be66a599dcf9ee
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 138e70c7c76dcb59f24715c31b6e322cd0bb8d3ee74ac4905f7e0d0ae7d206fc46481c5b47a76d970fc08a1f6a78aa17cb368ac43a79fe98c2251f29e1add74d
|
|
7
|
+
data.tar.gz: 8f92b011d2a6e1ee72547fcb8cba257accd972b2ff055eb88692c4701cdeabea00bf33bc4e0318e3cc9416078e587c1322911457c0f553ffde27f612bceb77c5
|
|
@@ -1,26 +1,80 @@
|
|
|
1
1
|
module Glib
|
|
2
|
-
# Class-level helper
|
|
3
|
-
#
|
|
4
|
-
#
|
|
5
|
-
# holding (see backend/01a_defensive_programming.md item 7).
|
|
2
|
+
# Class-level helper for declaring enums that read back as symbols, can never
|
|
3
|
+
# be persisted nil, and — crucially — know their attribute type even before
|
|
4
|
+
# the backing column exists.
|
|
6
5
|
#
|
|
7
|
-
#
|
|
6
|
+
# Preferred form (declares everything in one call; use INSTEAD of a bare
|
|
7
|
+
# `enum`). Because it calls `attribute` before `enum`, the enum's type comes
|
|
8
|
+
# from the declared values rather than from column introspection, so a model
|
|
9
|
+
# loaded against a not-yet-migrated column (fresh deploy, eager-loaded CI, an
|
|
10
|
+
# un-migrated local DB) no longer raises "Undeclared attribute type for enum":
|
|
8
11
|
#
|
|
9
12
|
# class Order < ApplicationRecord
|
|
10
|
-
#
|
|
11
|
-
# enum :finalize_intent, { unknown: 0, charge: 1 }, prefix: true
|
|
13
|
+
# include Glib::EnumSymbolization
|
|
12
14
|
#
|
|
13
|
-
# enum_symbolize :payment_status, :
|
|
15
|
+
# enum_symbolize :payment_status, { draft: 0, pending: 1, finalized: 2 }
|
|
16
|
+
# enum_symbolize :finalize_intent, { unknown: 0, charge: 1 }, prefix: true
|
|
14
17
|
# end
|
|
18
|
+
#
|
|
19
|
+
# The attribute type is inferred from the values: string values back a
|
|
20
|
+
# :string column, everything else (integer-keyed hashes, positional arrays)
|
|
21
|
+
# backs an :integer column. Pass the values as a *braced* hash — a bare
|
|
22
|
+
# `key: 0` list is parsed as keyword options, not values.
|
|
23
|
+
#
|
|
24
|
+
# Legacy form (attach presence + symbolized reader to enum(s) already declared
|
|
25
|
+
# above). Prefer the form above for new code:
|
|
26
|
+
#
|
|
27
|
+
# enum :status, { draft: 0, published: 1 }
|
|
28
|
+
# enum_symbolize :status
|
|
29
|
+
#
|
|
30
|
+
# Both forms add `validates :attr, presence: true` (a nil enum has no symbolic
|
|
31
|
+
# key and is almost always a bug) and override the reader to return a symbol,
|
|
32
|
+
# so callers can compare with `record.status == :active` without tracking
|
|
33
|
+
# which form they're holding (see backend/01a_defensive_programming.md item 7).
|
|
15
34
|
module EnumSymbolization
|
|
16
35
|
extend ActiveSupport::Concern
|
|
17
36
|
|
|
18
37
|
class_methods do
|
|
19
|
-
def enum_symbolize(*attrs)
|
|
20
|
-
attrs.
|
|
21
|
-
|
|
38
|
+
def enum_symbolize(*attrs, **opts)
|
|
39
|
+
if attrs.size >= 2 && (attrs[1].is_a?(Hash) || attrs[1].is_a?(Array))
|
|
40
|
+
# Full form: enum_symbolize :name, { ... }[, **enum_opts]
|
|
41
|
+
name, values = attrs
|
|
42
|
+
# MUST precede `enum`, and is NOT redundant: `enum` resolves its type
|
|
43
|
+
# by introspecting the DB column, which raises "Undeclared attribute
|
|
44
|
+
# type for enum" (RuntimeError) when the column isn't there yet — a
|
|
45
|
+
# not-yet-migrated column loaded on deploy, eager-loaded CI, or an
|
|
46
|
+
# un-migrated local DB. Declaring the attribute first pins the type
|
|
47
|
+
# from the enum's own values, so it no longer needs the column. Do not
|
|
48
|
+
# remove or move below `enum`.
|
|
49
|
+
attribute name, Glib::EnumSymbolization.backing_type(values)
|
|
50
|
+
enum name, values, **opts
|
|
51
|
+
glib_symbolize_reader(name)
|
|
52
|
+
else
|
|
53
|
+
# Legacy form: enum_symbolize :a[, :b, ...] for enums already declared.
|
|
54
|
+
if opts.any?
|
|
55
|
+
raise ArgumentError,
|
|
56
|
+
"enum_symbolize: pass enum values as a braced hash, " \
|
|
57
|
+
"e.g. enum_symbolize :#{attrs.first}, { ... }"
|
|
58
|
+
end
|
|
59
|
+
attrs.each { |attr| glib_symbolize_reader(attr) }
|
|
22
60
|
end
|
|
23
61
|
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def glib_symbolize_reader(attr)
|
|
66
|
+
validates attr, presence: true
|
|
67
|
+
define_method(attr) { super()&.to_sym }
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Infer the attribute type backing an enum from its declared values, so the
|
|
72
|
+
# type never depends on the (possibly not-yet-migrated) DB column. A hash
|
|
73
|
+
# whose values are strings backs a :string column; integer-keyed hashes and
|
|
74
|
+
# positional arrays back an :integer column.
|
|
75
|
+
def self.backing_type(values)
|
|
76
|
+
first = values.is_a?(Hash) ? values.values.first : nil
|
|
77
|
+
first.is_a?(String) ? :string : :integer
|
|
24
78
|
end
|
|
25
79
|
end
|
|
26
80
|
end
|
metadata
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: glib-web
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.0
|
|
4
|
+
version: 5.1.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- ''
|
|
8
|
+
autorequire:
|
|
8
9
|
bindir: bin
|
|
9
10
|
cert_chain: []
|
|
10
11
|
date: 2019-10-04 00:00:00.000000000 Z
|
|
@@ -149,6 +150,7 @@ dependencies:
|
|
|
149
150
|
- - ">="
|
|
150
151
|
- !ruby/object:Gem::Version
|
|
151
152
|
version: '0'
|
|
153
|
+
description:
|
|
152
154
|
email: ''
|
|
153
155
|
executables: []
|
|
154
156
|
extensions: []
|
|
@@ -527,8 +529,10 @@ files:
|
|
|
527
529
|
- lib/glib/value.rb
|
|
528
530
|
- lib/glib/version.rb
|
|
529
531
|
- lib/tasks/db.rake
|
|
532
|
+
homepage:
|
|
530
533
|
licenses: []
|
|
531
534
|
metadata: {}
|
|
535
|
+
post_install_message:
|
|
532
536
|
rdoc_options: []
|
|
533
537
|
require_paths:
|
|
534
538
|
- lib
|
|
@@ -543,7 +547,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
543
547
|
- !ruby/object:Gem::Version
|
|
544
548
|
version: '0'
|
|
545
549
|
requirements: []
|
|
546
|
-
rubygems_version: 4.
|
|
550
|
+
rubygems_version: 3.4.6
|
|
551
|
+
signing_key:
|
|
547
552
|
specification_version: 4
|
|
548
553
|
summary: ''
|
|
549
554
|
test_files: []
|