denormalize_fields 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: df06ff7f5808a0b48c771019d622d9d02bfd772077829b1aff1a82ebf6302fe9
4
+ data.tar.gz: 83d2f0339a9fceb7242426199ee062900aabfe88a18f252f9690e31773343e49
5
+ SHA512:
6
+ metadata.gz: 5318a68a0efb8f6975c815d2eda4c9e158100bfdb5d4cd3a1fc6c480e524315aa48b2b003bdf963a4f42a925dceca58186da2b7cccd3f4b94405dd753123b816
7
+ data.tar.gz: 1b60e2d7743d11c2cb3717f4ce1b64295f62b65d1316c325e93e049506375ab7692bbd7030089cd0b1567babc09c3211dafda1a285ddb9d133b7715aba6071d6
@@ -0,0 +1,62 @@
1
+ require 'denormalize_fields/association_extension'
2
+ require 'denormalize_fields/version'
3
+
4
+ module DenormalizeFields
5
+ module_function
6
+
7
+ def denormalize(fields:, from:, onto:, prefix: nil)
8
+ mapping = cast_to_mapping(fields, prefix: prefix)
9
+
10
+ from.after_save do
11
+ DenormalizeFields.call(record: self, relation_name: onto, mapping: mapping)
12
+ end
13
+ end
14
+
15
+ def cast_to_mapping(fields, prefix: nil)
16
+ if fields.is_a?(Hash)
17
+ prefix && raise(ArgumentError, 'pass EITHER a fields Hash OR a prefix')
18
+ fields
19
+ else
20
+ Array(fields).map { |e| [e.to_sym, [prefix, e].join.to_sym] }.to_h
21
+ end
22
+ end
23
+
24
+ def call(record:, relation_name:, mapping:)
25
+ changeset = DenormalizeFields.changeset(record: record, mapping: mapping)
26
+ return if changeset.empty?
27
+
28
+ Array(record.send(relation_name)).each do |related_record|
29
+ DenormalizeFields.apply(
30
+ changeset, to: related_record, owner: record, mapping: mapping
31
+ )
32
+ end
33
+ end
34
+
35
+ 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
38
+ end
39
+ end
40
+
41
+ # Note: missing related records are ignored, and new related records are not
42
+ # persisted. Extra options to raise/create/persist in this case might be nice.
43
+ def apply(changeset, to:, owner:, mapping:)
44
+ return if to.nil?
45
+
46
+ to.assign_attributes(changeset)
47
+ return if to.new_record? ? to.valid? : to.save
48
+
49
+ DenormalizeFields.copy_errors(to.errors, to_record: owner, mapping: mapping)
50
+ raise(ActiveRecord::RecordInvalid, to)
51
+ end
52
+
53
+ # TODO: use Errors#import when it becomes available in rails 6.1 or 6.2
54
+ def copy_errors(errors, to_record:, mapping:)
55
+ errors.details.each do |key, array|
56
+ field = mapping.rassoc(key.to_sym).first
57
+ array.each do |details|
58
+ to_record.errors.add(field, details[:error], details.except(:error))
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,3 @@
1
+ module DenormalizeFields
2
+ VERSION = '1.0.0'
3
+ end
metadata ADDED
@@ -0,0 +1,142 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: denormalize_fields
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Janosch Müller
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.1.14
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 7.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 4.1.14
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 7.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rails
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 4.1.14
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 7.0.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 4.1.14
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 7.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: rake
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rspec
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rspec-rails
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ - !ruby/object:Gem::Dependency
96
+ name: sqlite3
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - ">="
107
+ - !ruby/object:Gem::Version
108
+ version: '0'
109
+ description: 'This gem adds a `denormalize` option to ActiveRecord relation definitions,
110
+ e.g. `has_many :foos, denormalize: { fields: :updated_at }`.'
111
+ email:
112
+ - janosch84@gmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - lib/denormalize_fields.rb
118
+ - lib/denormalize_fields/version.rb
119
+ homepage: https://www.github.com/jaynetics/denormalize_fields
120
+ licenses:
121
+ - MIT
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: 2.3.0
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubygems_version: 3.1.2
139
+ signing_key:
140
+ specification_version: 4
141
+ summary: Simplify denormalizing fields from one record to another.
142
+ test_files: []