pico_phone-rails 0.1.0 → 0.2.1

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: a77136e5c4b12dd9a039e2fc5fb3a417bd6eae8e353c937f9c05b8c7b768fea4
4
- data.tar.gz: 6979e2642a4793889171a5de42a7f5bf209b486a4845488fd296b8af54821425
3
+ metadata.gz: a727b58fa9b03d91f9fed795d5f9b4898c8b6c1d416fa67eed38dc881c8a738a
4
+ data.tar.gz: 2727b559da6ec1a963f6b12f032aeeb9458eaacb5522e3ee98aabbb289863c28
5
5
  SHA512:
6
- metadata.gz: 8ee3cebc17f0fa5fa98ad427b763b024ad97114738d40e774739a50c04abe2c5c9082177fdefb31bd6e9a1a89ef9d026da6c1a0a7aafbca5c1c30473dd456366
7
- data.tar.gz: dffc493a5abe2b513629b9fa29cc7ac741d5181f7e128add7d592baeab92e4b3c757f3e9d5ecc2faf82067b76810498f681b15a5d0400dde53e5cd5e0d53d809
6
+ metadata.gz: f07be21c54bcd8f6f9f054af69875b7993f4428f6ef57a97d57252fcee3b71f540b1bcae6563568823c98960e4894afded9ec2e243178af10c36ff2a3dccca1d
7
+ data.tar.gz: 5b409b31ddbeaae09328eb1cbf6a98d392ad9cce01d5e047198c96149c6e985b9125baaa02c3557decbd1baacb6fc55e492203f9b9a76becd9386162474bad79
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # pico_phone-rails
2
2
 
3
3
  Rails integration for [`pico_phone`](https://github.com/gjack/pico_phone): an
4
- ActiveRecord attribute type, an ActiveModel validator, and a before-validation
5
- normalizer for phone numbers.
4
+ ActiveRecord attribute type, an ActiveModel validator, a before-validation
5
+ normalizer, and an ActiveJob serializer for phone numbers.
6
6
 
7
7
  ## Installation
8
8
 
@@ -52,6 +52,17 @@ A `before_validation` callback that rewrites the column to E.164 when it parses
52
52
  as valid, so formatting noise ("(510) 274-5656") is stripped before the
53
53
  validator runs. Pairs naturally with the validator above.
54
54
 
55
+ ### ActiveJob serializer
56
+
57
+ ```ruby
58
+ MyJob.perform_later(phone: PicoPhone.parse("+15102745656", "US"))
59
+ ```
60
+
61
+ A `PicoPhone::PhoneNumber` passed as a job argument survives the round trip
62
+ through your queue backend (Sidekiq, Solid Queue, GoodJob, etc.) without
63
+ manually converting to/from a string — `perform` receives back a real
64
+ `PhoneNumber`, not the E.164 string it was serialized as.
65
+
55
66
  ## Development
56
67
 
57
68
  ```bash
@@ -67,6 +78,11 @@ bundle exec appraisal install
67
78
  bundle exec appraisal rake
68
79
  ```
69
80
 
81
+ ## Contributing
82
+
83
+ Bug reports and pull requests are welcome on GitHub — see
84
+ [CONTRIBUTING.md](CONTRIBUTING.md) for setup and guidelines.
85
+
70
86
  ## License
71
87
 
72
88
  MIT — see [LICENSE.txt](LICENSE.txt).
@@ -6,8 +6,20 @@
6
6
  # including model's namespace up through Object, same convention the
7
7
  # email_validator gem uses.
8
8
  #
9
+ # @example
9
10
  # validates :phone, phone: { region: "US", allow_blank: true }
11
+ #
12
+ # @example Looser "possible" check instead of full validity
13
+ # validates :phone, phone: { region: "US", possible: true }
10
14
  class PhoneValidator < ActiveModel::EachValidator
15
+ # @param record [ActiveModel::Validations]
16
+ # @param attribute [Symbol]
17
+ # @param value [String, PicoPhone::PhoneNumber, nil]
18
+ # @option options [String] :region ISO 3166-1 alpha-2 default region used to interpret national-format input
19
+ # @option options [Boolean] :allow_blank skip validation when +value+ is +nil+ or empty
20
+ # @option options [Boolean] :possible use a looser possible?/possible_for_country? check instead of strict validity
21
+ # @option options [String] :message custom error message, passed through to +errors.add+
22
+ # @return [void]
11
23
  def validate_each(record, attribute, value)
12
24
  return if options[:allow_blank] && value.blank?
13
25
 
@@ -8,6 +8,7 @@ module PicoPhone
8
8
  # class macro that rewrites the given attributes to E.164 before validation
9
9
  # runs, so validators and persisted data see a consistent format.
10
10
  #
11
+ # @example
11
12
  # class Contact < ApplicationRecord
12
13
  # normalize_phone :phone, region: "US"
13
14
  # end
@@ -15,6 +16,13 @@ module PicoPhone
15
16
  extend ActiveSupport::Concern
16
17
 
17
18
  class_methods do
19
+ # @!method normalize_phone(*attributes, region: nil)
20
+ # Registers a +before_validation+ callback that rewrites each attribute
21
+ # to E.164 when it parses as valid, leaving unparseable input untouched
22
+ # so a validator can flag it.
23
+ # @param attributes [Array<Symbol>] attribute names to normalize
24
+ # @param region [String, nil] ISO 3166-1 alpha-2 default region used to interpret national-format input
25
+ # @return [void]
18
26
  def normalize_phone(*attributes, region: nil)
19
27
  before_validation do
20
28
  attributes.each do |attribute|
@@ -17,6 +17,13 @@ module PicoPhone
17
17
  end
18
18
  end
19
19
 
20
+ initializer "pico_phone_rails.active_job_serializer" do
21
+ ActiveSupport.on_load(:active_job) do
22
+ require "pico_phone/rails/serializers/phone_number_serializer"
23
+ ActiveJob::Serializers.add_serializers(PicoPhone::Rails::Serializers::PhoneNumberSerializer)
24
+ end
25
+ end
26
+
20
27
  initializer "pico_phone_rails.i18n" do |app|
21
28
  app.config.i18n.load_path += Dir[File.expand_path("locale/*.yml", __dir__)]
22
29
  end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module PicoPhone
4
+ module Rails
5
+ module Serializers
6
+ # Registered with ActiveJob::Serializers in the railtie, only once
7
+ # ActiveJob itself has loaded. Lets a PhoneNumber survive as a job
8
+ # argument without the caller manually converting to/from a string.
9
+ #
10
+ # #to_s alone is enough to round-trip losslessly: E.164 is
11
+ # region-independent for valid numbers, and for invalid/unparseable
12
+ # input #to_s already falls back to the original string, which
13
+ # reparses to the same #to_s/#valid? regardless of region.
14
+ #
15
+ # @example
16
+ # MyJob.perform_later(phone: PicoPhone.parse("+15102745656", "US"))
17
+ class PhoneNumberSerializer < ActiveJob::Serializers::ObjectSerializer
18
+ # @param phone_number [PicoPhone::PhoneNumber]
19
+ # @return [Hash] JSON-safe payload; ActiveJob merges in its own reserved serializer-identity key
20
+ def serialize(phone_number)
21
+ super("value" => phone_number.to_s)
22
+ end
23
+
24
+ # @param hash [Hash] payload previously produced by {#serialize}
25
+ # @return [PicoPhone::PhoneNumber]
26
+ def deserialize(hash)
27
+ PicoPhone.parse(hash["value"])
28
+ end
29
+
30
+ # The class this serializer handles -- ActiveJob::Serializers uses it
31
+ # both for dispatch (default #serialize?) and, since ActiveJob 8.1, to
32
+ # build a lookup index, which is why it must be public: earlier
33
+ # ActiveJob versions accepted a private #klass, but 8.1+ warns (and
34
+ # 8.2+ will raise) if it isn't public.
35
+ # @return [Class]
36
+ def klass
37
+ PicoPhone::PhoneNumber
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -7,17 +7,25 @@ module PicoPhone
7
7
  # Registered as `:phone_number` in the railtie. Casts a stored string to a
8
8
  # PicoPhone::PhoneNumber on read and serializes back to E.164 on write.
9
9
  #
10
+ # @example
10
11
  # attribute :phone, :phone_number, region: "US"
12
+ #
13
+ # contact.phone # => #<PicoPhone::PhoneNumber ...>
14
+ # contact.phone.e164 # => "+15102745656"
11
15
  class Type < ActiveModel::Type::Value
16
+ # @param region [String, nil] ISO 3166-1 alpha-2 default region used to interpret national-format input
12
17
  def initialize(region: nil)
13
18
  @region = region
14
19
  super()
15
20
  end
16
21
 
22
+ # @return [Symbol] always +:string+ -- the underlying column stores a plain string
17
23
  def type
18
24
  :string
19
25
  end
20
26
 
27
+ # @param value [String, PicoPhone::PhoneNumber, nil]
28
+ # @return [PicoPhone::PhoneNumber, nil] +nil+ for +nil+ input; never raises on unparseable input
21
29
  def cast(value)
22
30
  return value if value.is_a?(PicoPhone::PhoneNumber)
23
31
  return nil if value.nil?
@@ -25,6 +33,8 @@ module PicoPhone
25
33
  PicoPhone.parse(value.to_s, @region)
26
34
  end
27
35
 
36
+ # @param value [String, PicoPhone::PhoneNumber, nil]
37
+ # @return [String, nil] E.164 for a valid number, the original string for an invalid one, +nil+ for +nil+ input
28
38
  def serialize(value)
29
39
  return nil if value.nil?
30
40
 
@@ -32,6 +42,8 @@ module PicoPhone
32
42
  phone_number.valid? ? phone_number.e164 : phone_number.to_s
33
43
  end
34
44
 
45
+ # @param value [String, nil] raw value read from the database
46
+ # @return [PicoPhone::PhoneNumber, nil]
35
47
  def deserialize(value)
36
48
  cast(value)
37
49
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module PicoPhone
4
4
  module Rails
5
- VERSION = "0.1.0"
5
+ VERSION = "0.2.1"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pico_phone-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gabi Jack
@@ -52,8 +52,9 @@ dependencies:
52
52
  - !ruby/object:Gem::Version
53
53
  version: '7.0'
54
54
  description: 'pico_phone-rails wires the pico_phone gem into Rails: a :phone_number
55
- ActiveRecord attribute type, a PhoneValidator for ActiveModel validations, and a
56
- normalize_phone class macro that rewrites phone attributes to E.164 before validation.'
55
+ ActiveRecord attribute type, a PhoneValidator for ActiveModel validations, a normalize_phone
56
+ class macro that rewrites phone attributes to E.164 before validation, and an ActiveJob
57
+ serializer so a PhoneNumber survives being passed as a job argument.'
57
58
  email:
58
59
  - gabi@gabijack.com
59
60
  executables: []
@@ -67,6 +68,7 @@ files:
67
68
  - lib/pico_phone/rails/locale/en.yml
68
69
  - lib/pico_phone/rails/normalizer.rb
69
70
  - lib/pico_phone/rails/railtie.rb
71
+ - lib/pico_phone/rails/serializers/phone_number_serializer.rb
70
72
  - lib/pico_phone/rails/type.rb
71
73
  - lib/pico_phone/rails/version.rb
72
74
  homepage: https://github.com/gjack/pico_phone-rails
@@ -77,6 +79,7 @@ metadata:
77
79
  source_code_uri: https://github.com/gjack/pico_phone-rails
78
80
  changelog_uri: https://github.com/gjack/pico_phone-rails/releases
79
81
  bug_tracker_uri: https://github.com/gjack/pico_phone-rails/issues
82
+ documentation_uri: https://rubydoc.info/gems/pico_phone-rails
80
83
  rubygems_mfa_required: 'true'
81
84
  rdoc_options: []
82
85
  require_paths:
@@ -94,6 +97,6 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
97
  requirements: []
95
98
  rubygems_version: 3.6.9
96
99
  specification_version: 4
97
- summary: 'Rails integration for pico_phone: attribute type, validator, and normalizer
98
- for phone numbers'
100
+ summary: 'Rails integration for pico_phone: attribute type, validator, normalizer,
101
+ and ActiveJob serializer'
99
102
  test_files: []