denormalize_fields 1.1.1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7bf731da26d483667dbb6a1942755bdf5c6cf5161aaf1b2d9fb1b2dc84366d96
4
- data.tar.gz: a8e09ec6ced26720d404ca8e693f1e9c036a92b01b9f7d607b8cb6a51587112f
3
+ metadata.gz: b9b1cb8a3c118b8e410665f182f78fd63ec1dfa571af98f2d93f5deca9e0600a
4
+ data.tar.gz: 73785e5dc16509d33978fcc22571e9dc961d9c5dd02e712b640d4a57d8bb8a2f
5
5
  SHA512:
6
- metadata.gz: d3cb5a23f3896d6074020c48e53b954f0e4266a779da1b7c106d8bc5d0df6f22597bcab869ef9872d14aa23de163aa5b6d2df1e7904ac66a190d9546b462d462
7
- data.tar.gz: 75c819d17a023f5fbbade955cb90ee54417e4a22807ab78fb924aff011611bf4d858fbf7cfad1eb63bbf9fe2807f0897c6d89a0be87cde2902757bf08266fbdb
6
+ metadata.gz: 5836ceeb70a8d592d5f9406c6b6c79bd6d0ffe51f5a80b4e3ab202983aba5ec0526ec30fe7a561b02e78da97578a10a8509be898c9a208e9dc3e043417c2387c
7
+ data.tar.gz: 8f87ae5f9efae07bd63eab9e5394d5b78cd6162569583327cac0c086dc244899d718c69ce2c50aa4039d4b35ea21d268641ce83892bdb44df0a899b0e50575e7
@@ -12,10 +12,9 @@ module DenormalizeFields
12
12
  return unless options = association.options[OPTION]
13
13
 
14
14
  DenormalizeFields.denormalize(
15
- fields: options[:fields],
16
- from: association.active_record,
17
- onto: association.name,
18
- prefix: options[:prefix],
15
+ from: association.active_record,
16
+ onto: association.name,
17
+ **options,
19
18
  )
20
19
  end
21
20
  end
@@ -1,3 +1,3 @@
1
1
  module DenormalizeFields
2
- VERSION = '1.1.1'
2
+ VERSION = '1.3.0'
3
3
  end
@@ -4,14 +4,48 @@ require 'denormalize_fields/version'
4
4
  module DenormalizeFields
5
5
  module_function
6
6
 
7
- def denormalize(fields:, from:, onto:, prefix: nil)
7
+ class ArgumentError < ::ArgumentError; end
8
+
9
+ class RelatedRecordInvalid < ::ActiveRecord::RecordInvalid
10
+ attr_accessor :owner, :mapping
11
+
12
+ def initialize(record:, owner:, mapping:)
13
+ super(record)
14
+ self.owner = owner
15
+ self.mapping = mapping
16
+ end
17
+ end
18
+
19
+ def denormalize(fields:, from:, onto:, prefix: nil, **options)
8
20
  mapping = cast_to_mapping(fields, prefix: prefix)
21
+ validate_options(**options)
9
22
 
10
23
  from.after_save do
11
- DenormalizeFields.call(record: self, relation_name: onto, mapping: mapping)
24
+ DenormalizeFields.call(
25
+ record: self,
26
+ relation_name: onto,
27
+ mapping: mapping,
28
+ **options,
29
+ )
12
30
  end
13
31
  end
14
32
 
33
+ def validate_options(**options)
34
+ validate_conditional(options[:if])
35
+ validate_conditional(options[:unless])
36
+ unsupported = (options.keys - %i[if unless]).empty? ||
37
+ raise(ArgumentError, "unsupported denormalize options: #{unsupported}")
38
+ end
39
+
40
+ CONDITIONAL_CLASSES = [NilClass, TrueClass, FalseClass, Symbol, Proc]
41
+
42
+ def validate_conditional(arg)
43
+ CONDITIONAL_CLASSES.include?(arg.class) || raise(
44
+ ArgumentError,
45
+ "`if:` option must be a #{CONDITIONAL_CLASSES.join('/')}, got: #{arg.class}"
46
+ )
47
+ end
48
+
15
49
  def cast_to_mapping(fields, prefix: nil)
16
50
  if fields.is_a?(Hash)
17
51
  prefix && raise(ArgumentError, 'pass EITHER a fields Hash OR a prefix')
@@ -21,7 +55,10 @@ module DenormalizeFields
21
55
  end
22
56
  end
23
57
 
24
- def call(record:, relation_name:, mapping:)
58
+ def call(record:, relation_name:, mapping:, **options)
59
+ return unless conditional_passes?(options[:if], record, false)
60
+ return unless conditional_passes?(options[:unless], record, true)
61
+
25
62
  changeset = DenormalizeFields.changeset(record: record, mapping: mapping)
26
63
  return if changeset.empty?
27
64
 
@@ -32,6 +69,21 @@ module DenormalizeFields
32
69
  end
33
70
  end
34
71
 
72
+ def conditional_passes?(conditional, record, inverted)
73
+ return true if conditional.nil?
74
+
75
+ result =
76
+ if conditional.respond_to?(:call)
77
+ record.instance_exec(&conditional)
78
+ elsif conditional.class == Symbol
79
+ record.send(conditional)
80
+ else # true, false
81
+ conditional
82
+ end
83
+
84
+ inverted ? !result : !!result
85
+ end
86
+
35
87
  def changeset(record:, mapping:)
36
88
  mapping.each.with_object({}) do |(source, dest), hash|
37
89
  if source.is_a?(Array)
@@ -54,15 +106,16 @@ module DenormalizeFields
54
106
  return if to.new_record? ? to.valid? : to.save
55
107
 
56
108
  DenormalizeFields.copy_errors(to.errors, to_record: owner, mapping: mapping)
57
- raise(ActiveRecord::RecordInvalid, to)
109
+ raise RelatedRecordInvalid.new(record: to, owner: owner, mapping: mapping)
58
110
  end
59
111
 
60
112
  # TODO: use Errors#import when it becomes available in rails 6.1 or 6.2
61
113
  def copy_errors(errors, to_record:, mapping:)
62
114
  errors.details.each do |key, array|
63
- field = mapping.rassoc(key.to_sym).first
64
- array.each do |details|
65
- to_record.errors.add(field, details[:error], details.except(:error))
115
+ Array(mapping.rassoc(key.to_sym)).compact.each do |field|
116
+ array.each do |details|
117
+ to_record.errors.add(field, details[:error], **details.except(:error))
118
+ end
66
119
  end
67
120
  end
68
121
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: denormalize_fields
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.1
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Janosch Müller
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-03-26 00:00:00.000000000 Z
11
+ date: 2021-12-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 4.1.14
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: 7.0.0
22
+ version: 8.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,27 +29,21 @@ dependencies:
29
29
  version: 4.1.14
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: 7.0.0
32
+ version: 8.0.0
33
33
  - !ruby/object:Gem::Dependency
34
34
  name: rails
35
35
  requirement: !ruby/object:Gem::Requirement
36
36
  requirements:
37
- - - ">="
38
- - !ruby/object:Gem::Version
39
- version: 4.1.14
40
- - - "<"
37
+ - - "~>"
41
38
  - !ruby/object:Gem::Version
42
- version: 7.0.0
39
+ version: '7.0'
43
40
  type: :development
44
41
  prerelease: false
45
42
  version_requirements: !ruby/object:Gem::Requirement
46
43
  requirements:
47
- - - ">="
48
- - !ruby/object:Gem::Version
49
- version: 4.1.14
50
- - - "<"
44
+ - - "~>"
51
45
  - !ruby/object:Gem::Version
52
- version: 7.0.0
46
+ version: '7.0'
53
47
  - !ruby/object:Gem::Dependency
54
48
  name: rake
55
49
  requirement: !ruby/object:Gem::Requirement
@@ -121,7 +115,7 @@ homepage: https://www.github.com/jaynetics/denormalize_fields
121
115
  licenses:
122
116
  - MIT
123
117
  metadata: {}
124
- post_install_message:
118
+ post_install_message:
125
119
  rdoc_options: []
126
120
  require_paths:
127
121
  - lib
@@ -136,8 +130,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
130
  - !ruby/object:Gem::Version
137
131
  version: '0'
138
132
  requirements: []
139
- rubygems_version: 3.1.2
140
- signing_key:
133
+ rubygems_version: 3.2.32
134
+ signing_key:
141
135
  specification_version: 4
142
136
  summary: Simplify denormalizing fields from one record to another.
143
137
  test_files: []