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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 66abe13aca7ef703ab65bcbaeded784ff74339b4dcfd3659658bdefc99f0ec30
4
- data.tar.gz: a8c90ab7a9684a4eeed86c8d6e25d3676281157c856ed07cd582b5ccdebfa622
3
+ metadata.gz: 9af6a7a8e8f3cd4b9a45446e58347ff9ecc2130d1ce4f715da68ead1c7646ab5
4
+ data.tar.gz: 3239c38d6b96f609eb961d5e427121bee47804430475bc0fe0be66a599dcf9ee
5
5
  SHA512:
6
- metadata.gz: ef265df7cd0d8f0e3d951f384b574cf01e6c4039f774e0df286fb0617ce58be80551cb5e1ccbf05996af4b9127aaa8cfdccbac7f146d22b0816acc6690400814
7
- data.tar.gz: e5ba874af4579d1310671a292404a2cb27b8ff89b609ff2a2c0f0ff3609a301a8566d8e3a86099d4a41c9ca6249a19cd00ce78a4cef30c8642e85efed260f07a
6
+ metadata.gz: 138e70c7c76dcb59f24715c31b6e322cd0bb8d3ee74ac4905f7e0d0ae7d206fc46481c5b47a76d970fc08a1f6a78aa17cb368ac43a79fe98c2251f29e1add74d
7
+ data.tar.gz: 8f92b011d2a6e1ee72547fcb8cba257accd972b2ff055eb88692c4701cdeabea00bf33bc4e0318e3cc9416078e587c1322911457c0f553ffde27f612bceb77c5
@@ -1,26 +1,80 @@
1
1
  module Glib
2
- # Class-level helper that overrides one or more enum readers to return a
3
- # symbol instead of Rails' default string form. Lets callers compare with
4
- # `record.status == :active` without having to remember which form they're
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
- # Usage:
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
- # enum :payment_status, { draft: 0, pending: 1, finalized: 2 }
11
- # enum :finalize_intent, { unknown: 0, charge: 1 }, prefix: true
13
+ # include Glib::EnumSymbolization
12
14
  #
13
- # enum_symbolize :payment_status, :finalize_intent
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.each do |attr|
21
- define_method(attr) { super()&.to_sym }
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.9
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.0.6
550
+ rubygems_version: 3.4.6
551
+ signing_key:
547
552
  specification_version: 4
548
553
  summary: ''
549
554
  test_files: []