denormalize_fields 1.0.1 → 1.2.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: 0236da61bb8d620a30c1d80b5e2915655c3fa172209e48e4a0574319bab02318
4
- data.tar.gz: 186179fca7937e35b792f44d859c58febe38bdc28c1ea7e41b347a7280919d02
3
+ metadata.gz: f75e3e551412d74ece84cd1369cf35350d9bf089fe1fecb2a635983dae2c8aaf
4
+ data.tar.gz: 4bb30e1378174f374fddbd41e48857236a1991ee828f7c440b518f910273f870
5
5
  SHA512:
6
- metadata.gz: 18db814fcaaa2e8a8c9dcf48469ab6e464a231157d5e5c8cd23293b8c11279df911ccd591536aab593b3ab9e2507bb87db5ed7de55228cea99434d201c9d53be
7
- data.tar.gz: 302b99956194d9fd94c47fa60a9aa5198b82fe7052b74f88fcdd87dc8945dd2c44644b217e6c81738df55c71f35804c98f3f4646c940b56a5195ab9cce680af3
6
+ metadata.gz: d4987aec2cf44f282450b8a6a6aaf2bc80af4ca362c31fcf05320328a9b4cda4db0f3ffda7e2744ce0352bb08b533285d705a2c29a327ac6a499580c58b9d034
7
+ data.tar.gz: e5460b437851d87fd9be891f10c921e1160e93184a186a97435bc059d32b5a07ce0fe8d9ee50e1724282fe6c0a2e66764bcb250cb79df5f900fb1a11c6516775
@@ -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.0.1'
2
+ VERSION = '1.2.0'
3
3
  end
@@ -4,14 +4,36 @@ require 'denormalize_fields/version'
4
4
  module DenormalizeFields
5
5
  module_function
6
6
 
7
- def denormalize(fields:, from:, onto:, prefix: nil)
7
+ def denormalize(fields:, from:, onto:, prefix: nil, **options)
8
8
  mapping = cast_to_mapping(fields, prefix: prefix)
9
+ validate_options(**options)
9
10
 
10
11
  from.after_save do
11
- DenormalizeFields.call(record: self, relation_name: onto, mapping: mapping)
12
+ DenormalizeFields.call(
13
+ record: self,
14
+ relation_name: onto,
15
+ mapping: mapping,
16
+ **options,
17
+ )
12
18
  end
13
19
  end
14
20
 
21
+ def validate_options(**options)
22
+ validate_conditional(options[:if])
23
+ validate_conditional(options[:unless])
24
+ unsupported = (options.keys - %i[if unless]).empty? ||
25
+ raise(ArgumentError, "unsupported denormalize options: #{unsupported}")
26
+ end
27
+
28
+ CONDITIONAL_CLASSES = [NilClass, TrueClass, FalseClass, Symbol, Proc]
29
+
30
+ def validate_conditional(arg)
31
+ CONDITIONAL_CLASSES.include?(arg.class) || raise(
32
+ ArgumentError,
33
+ "`if:` option must be a #{CONDITIONAL_CLASSES.join('/')}, got: #{arg.class}"
34
+ )
35
+ end
36
+
15
37
  def cast_to_mapping(fields, prefix: nil)
16
38
  if fields.is_a?(Hash)
17
39
  prefix && raise(ArgumentError, 'pass EITHER a fields Hash OR a prefix')
@@ -21,7 +43,10 @@ module DenormalizeFields
21
43
  end
22
44
  end
23
45
 
24
- def call(record:, relation_name:, mapping:)
46
+ def call(record:, relation_name:, mapping:, **options)
47
+ return unless conditional_passes?(options[:if], record, false)
48
+ return unless conditional_passes?(options[:unless], record, true)
49
+
25
50
  changeset = DenormalizeFields.changeset(record: record, mapping: mapping)
26
51
  return if changeset.empty?
27
52
 
@@ -32,9 +57,31 @@ module DenormalizeFields
32
57
  end
33
58
  end
34
59
 
60
+ def conditional_passes?(conditional, record, inverted)
61
+ return true if conditional.nil?
62
+
63
+ result =
64
+ if conditional.respond_to?(:call)
65
+ record.instance_exec(&conditional)
66
+ elsif conditional.class == Symbol
67
+ record.send(conditional)
68
+ else # true, false
69
+ conditional
70
+ end
71
+
72
+ inverted ? !result : !!result
73
+ end
74
+
35
75
  def changeset(record:, mapping:)
36
- record.saved_changes.slice(*mapping.keys).each.with_object({}) do |(k, v), a|
37
- a[mapping.fetch(k.to_sym)] = v.last
76
+ mapping.each.with_object({}) do |(source, dest), hash|
77
+ if source.is_a?(Array)
78
+ if source.any? { |field| record.saved_change_to_attribute?(field) }
79
+ current_values = record.attributes.values_at(*source.map(&:to_s))
80
+ hash[dest] = current_values.join(' ')
81
+ end
82
+ elsif change = record.saved_change_to_attribute(source)
83
+ hash[dest] = change.last
84
+ end
38
85
  end
39
86
  end
40
87
 
@@ -55,7 +102,7 @@ module DenormalizeFields
55
102
  errors.details.each do |key, array|
56
103
  field = mapping.rassoc(key.to_sym).first
57
104
  array.each do |details|
58
- to_record.errors.add(field, details[:error], details.except(:error))
105
+ to_record.errors.add(field, details[:error], **details.except(:error))
59
106
  end
60
107
  end
61
108
  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.0.1
4
+ version: 1.2.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-02-13 00:00:00.000000000 Z
11
+ date: 2021-11-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -121,7 +121,7 @@ homepage: https://www.github.com/jaynetics/denormalize_fields
121
121
  licenses:
122
122
  - MIT
123
123
  metadata: {}
124
- post_install_message:
124
+ post_install_message:
125
125
  rdoc_options: []
126
126
  require_paths:
127
127
  - lib
@@ -136,8 +136,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
136
136
  - !ruby/object:Gem::Version
137
137
  version: '0'
138
138
  requirements: []
139
- rubygems_version: 3.1.2
140
- signing_key:
139
+ rubygems_version: 3.2.3
140
+ signing_key:
141
141
  specification_version: 4
142
142
  summary: Simplify denormalizing fields from one record to another.
143
143
  test_files: []