denormalize_fields 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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: []