loggable_activity 0.1.56 → 0.1.58

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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +10 -1
  3. data/CHANGELOG.md +9 -0
  4. data/GETTING-STARTED.md +8 -47
  5. data/PAYLOAD_EXAMPLE.md +63 -0
  6. data/docs/LoggableActivity/Activity.html +92 -241
  7. data/docs/LoggableActivity/Configuration.html +162 -15
  8. data/docs/LoggableActivity/ConfigurationError.html +148 -0
  9. data/docs/LoggableActivity/DataOwner.html +138 -0
  10. data/docs/LoggableActivity/Encryption.html +18 -14
  11. data/docs/LoggableActivity/EncryptionError.html +47 -1
  12. data/docs/LoggableActivity/EncryptionKey.html +54 -35
  13. data/docs/LoggableActivity/Error.html +48 -0
  14. data/docs/LoggableActivity/Hooks.html +221 -89
  15. data/docs/LoggableActivity/Payload.html +103 -27
  16. data/docs/LoggableActivity/Services/BasePayloadsBuilder.html +442 -0
  17. data/docs/LoggableActivity/Services/DestroyPayloadsBuilder.html +395 -0
  18. data/docs/LoggableActivity/Services/PayloadsBuilder.html +342 -0
  19. data/docs/LoggableActivity/Services/UpdatePayloadsBuilder.html +490 -0
  20. data/docs/LoggableActivity/Services.html +93 -0
  21. data/docs/created.rid +14 -10
  22. data/docs/index.html +10 -2
  23. data/docs/js/navigation.js.gz +0 -0
  24. data/docs/js/search_index.js +1 -1
  25. data/docs/js/search_index.js.gz +0 -0
  26. data/docs/js/searcher.js.gz +0 -0
  27. data/docs/table_of_contents.html +253 -85
  28. data/lib/generators/loggable_activity/install_generator.rb +2 -18
  29. data/lib/generators/loggable_activity/templates/binary_ids/create_loggable_activities.rb +9 -10
  30. data/lib/generators/loggable_activity/templates/create_loggable_activities.rb +16 -13
  31. data/lib/loggable_activity/activity.rb +53 -102
  32. data/lib/loggable_activity/configuration.rb +60 -3
  33. data/lib/loggable_activity/data_owner.rb +18 -0
  34. data/lib/loggable_activity/encryption.rb +14 -14
  35. data/lib/loggable_activity/encryption_key.rb +26 -25
  36. data/lib/loggable_activity/error.rb +34 -0
  37. data/lib/loggable_activity/hooks.rb +78 -43
  38. data/lib/loggable_activity/payload.rb +70 -20
  39. data/lib/loggable_activity/services/base_payloads_builder.rb +127 -0
  40. data/lib/loggable_activity/services/destroy_payloads_builder.rb +127 -0
  41. data/lib/loggable_activity/services/payloads_builder.rb +98 -0
  42. data/lib/loggable_activity/services/update_payloads_builder.rb +168 -0
  43. data/lib/loggable_activity/version.rb +1 -1
  44. data/lib/loggable_activity.rb +6 -6
  45. data/lib/schemas/config_schema.json +90 -0
  46. metadata +37 -26
  47. data/docs/LoggableActivity/PayloadsBuilder.html +0 -441
  48. data/docs/LoggableActivity/UpdatePayloadsBuilder.html +0 -424
  49. data/lib/generators/loggable_activity/install_templates_generator.rb +0 -105
  50. data/lib/generators/loggable_activity/templates/helpers/activity_helper.rb +0 -37
  51. data/lib/generators/loggable_activity/templates/helpers/router.rb +0 -52
  52. data/lib/generators/loggable_activity/templates/helpers/routes_helper.rb +0 -20
  53. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_create.html.erb +0 -23
  54. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_create.html.slim +0 -18
  55. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_destroy.html.erb +0 -18
  56. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_destroy.html.slim +0 -17
  57. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_show.html.erb +0 -18
  58. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_show.html.slim +0 -17
  59. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_update.html.erb +0 -18
  60. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/default/_update.html.slim +0 -12
  61. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_activity_info.html.erb +0 -12
  62. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_activity_info.html.slim +0 -11
  63. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_list_attrs.html.erb +0 -8
  64. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_list_attrs.html.slim +0 -6
  65. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_update_attrs.html.erb +0 -17
  66. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_update_attrs.html.slim +0 -14
  67. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_updated_relations.html.erb +0 -23
  68. data/lib/generators/loggable_activity/templates/views/loggable_activity/templates/shared/_updated_relations.html.slim +0 -21
  69. data/lib/loggable_activity/payloads_builder.rb +0 -153
  70. data/lib/loggable_activity/update_payloads_builder.rb +0 -127
@@ -1,23 +0,0 @@
1
- <tr>
2
- <td>
3
- <%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
4
- </td>
5
- <td>
6
- <b class="text-secondary"><%= primary_type(activity) %></b>
7
- <br>
8
- <% activity.primary_payload_attrs.each do |k, v| %>
9
- <%= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe %>
10
- <br>
11
- <% end %>
12
- <br>
13
- <% activity.relations_attrs.each do |relation_attrs| %>
14
- <b class="text-secondary"><%= relation_type(relation_attrs) %></b>
15
- <br>
16
- <%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] } %>
17
- <br>
18
- <% end %>
19
- </td>
20
- <td>
21
- <%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
22
- </td>
23
- </tr>
@@ -1,18 +0,0 @@
1
- tr
2
- td
3
- = render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
4
- td
5
- b.text-secondary = primary_type(activity)
6
- br
7
- - activity.primary_payload_attrs.each do |k, v|
8
- = "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
9
- br/
10
- br
11
- - activity.relations_attrs.each do |relation_attrs|
12
- b.text-secondary = relation_type(relation_attrs)
13
- br/
14
- =
15
- = render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] }
16
- br/
17
- td
18
- =< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
@@ -1,18 +0,0 @@
1
- <tr>
2
- <td>
3
- <%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
4
- </td>
5
- <td>
6
- <% update_activity_attrs = activity.update_activity_attrs %>
7
- <% if update_attrs = update_activity_attrs[:update_attrs] %>
8
- <%= render partial: 'loggable_activity/templates/shared/update_attrs', locals: { update_attrs: update_attrs } %>
9
- <% end %>
10
- <% if updated_relations = update_activity_attrs[:updated_relations_attrs] %>
11
- <br>
12
- <%= render partial: 'loggable_activity/templates/shared/updated_relations', locals: { updated_relations: updated_relations } %>
13
- <% end %>
14
- </td>
15
- <td>
16
- <%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
17
- </td>
18
- </tr>
@@ -1,17 +0,0 @@
1
- tr
2
- td
3
- = render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
4
- td
5
- b.text-secondary = primary_type(activity)
6
- br/
7
- - activity.primary_payload_attrs.each do |k, v|
8
- = "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
9
- br/
10
- br/
11
- - activity.relations_attrs.each do |relation_attrs|
12
- b.text-secondary = relation_type(relation_attrs)
13
- br/
14
- = render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] }
15
- br/
16
- td
17
- =< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
@@ -1,18 +0,0 @@
1
- <tr>
2
- <td>
3
- <%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
4
- </td>
5
- <td>
6
- <b class="text-secondary"><%= primary_type(activity) %></b><br/>
7
- <% activity.primary_payload_attrs.each do |k, v| %>
8
- <%= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe %><br/>
9
- <% end %><br/>
10
- <% activity.relations_attrs.each do |relation_attrs| %>
11
- <b class="text-secondary"><%= relation_type(relation_attrs) %></b><br/>
12
- <%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] } %><br/>
13
- <% end %>
14
- </td>
15
- <td>
16
- <%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
17
- </td>
18
- </tr>
@@ -1,17 +0,0 @@
1
- tr
2
- td
3
- = render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
4
- td
5
- b.text-secondary = primary_type(activity)
6
- br/
7
- - activity.primary_payload_attrs.each do |k, v|
8
- = "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
9
- br/
10
- br/
11
- - activity.relations_attrs.each do |relation_attrs|
12
- b.text-secondary = relation_type(relation_attrs)
13
- br/
14
- = render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation_attrs[:attrs] }
15
- br/
16
- td
17
- =< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
@@ -1,18 +0,0 @@
1
- <tr>
2
- <td>
3
- <%= render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity } %>
4
- </td>
5
- <td>
6
- <% update_activity_attrs = activity.update_activity_attrs %>
7
- <% if update_attrs = update_activity_attrs[:update_attrs] %>
8
- <%= render partial: 'loggable_activity/templates/shared/update_attrs', locals: { update_attrs: update_attrs } %>
9
- <% end %>
10
- <% if updated_relations = update_activity_attrs[:updated_relations_attrs] %>
11
- <br>
12
- <%= render partial: 'loggable_activity/templates/shared/updated_relations', locals: { updated_relations: updated_relations } %>
13
- <% end %>
14
- </td>
15
- <td>
16
- <%= link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm' %>
17
- </td>
18
- </tr>
@@ -1,12 +0,0 @@
1
- tr
2
- td
3
- = render partial: 'loggable_activity/templates/shared/activity_info', locals: { activity: activity }
4
- td
5
- - update_activity_attrs = activity.update_activity_attrs
6
- - if update_attrs = update_activity_attrs[:update_attrs]
7
- = render partial: 'loggable_activity/templates/shared/update_attrs', locals: { update_attrs: update_attrs }
8
- - if updated_relations = update_activity_attrs[:updated_relations_attrs]
9
- br/
10
- = render partial: 'loggable_activity/templates/shared/updated_relations', locals: { updated_relations: updated_relations }
11
- td
12
- =< link_to 'Delete', demo_activity_log_path(activity), data: { turbo_method: :delete, confirm: 'Are you sure?' }, class: 'btn btn-danger btn-sm'
@@ -1,12 +0,0 @@
1
- <div class="px-4">
2
- <h5><%= t("loggable.activity.#{activity.action}", name: "") %></h5>
3
- <b><%= activity.record_display_name %></b>
4
- <br>
5
- <i>Actor:&nbsp;</i>
6
- <br>
7
- <%= activity.actor_display_name %>
8
- <br>
9
- <i>When:&nbsp;</i>
10
- <br>
11
- <%= I18n.l(activity.created_at, format: :long) %>
12
- </div>
@@ -1,11 +0,0 @@
1
- .px-4
2
- .h5 = t("loggable.activity.#{activity.action}", name: "")
3
- b = activity.record_display_name
4
- br
5
- i Actor:&nbsp;
6
- br
7
- = activity.actor_display_name
8
- br
9
- i When:&nbsp;
10
- br
11
- = I18n.l(activity.created_at, format: :long)
@@ -1,8 +0,0 @@
1
- <% if attrs == :deleted %>
2
- <%= t('loggable.activity.deleted') %>
3
- <% elsif attrs.is_a?(Hash) %>
4
- <% attrs.each do |k, v| %>
5
- <%= "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe %>
6
- <br>
7
- <% end %>
8
- <% end %>
@@ -1,6 +0,0 @@
1
- - if attrs == :deleted
2
- = t('loggable.activity.deleted')
3
- - elsif attrs.is_a?(Hash)
4
- - attrs.each do |k, v|
5
- = "<i>#{k}:</i> #{v.blank? ? t('loggable.activity.deleted') : v}".html_safe
6
- br/
@@ -1,17 +0,0 @@
1
- <b class="text-secondary"><%= update_relation_class(update_attrs) %></b>
2
- <br>
3
- <% if update_attrs[:attrs] == :deleted %>
4
- <%= t('loggable.activity.deleted') %>
5
- <% else %>
6
- <% update_attrs[:attrs].each do |attr| %>
7
- <% attr.each do |key, from_to| %>
8
- <% next if from_to.nil? %>
9
- <i><%= key %></i>
10
- <br>
11
- <%= "from: #{from_to[:from].nil? ? 'Empty' : from_to[:from]}" %>
12
- <br>
13
- <%= "to: #{from_to[:to].nil? ? 'Empty' : from_to[:to]}" %>
14
- <br>
15
- <% end %>
16
- <% end %>
17
- <% end %>
@@ -1,14 +0,0 @@
1
- b.text-secondary = update_relation_class(update_attrs)
2
- br/
3
- - if update_attrs[:attrs] == :deleted
4
- = t('loggable.activity.deleted')
5
- - else
6
- - update_attrs[:attrs].each do |attr|
7
- - attr.each do |key, from_to|
8
- - next if from_to.nil?
9
- i = key
10
- br/
11
- = "from: #{from_to[:from].nil? ? "Empty" : from_to[:from]}"
12
- br/
13
- = "to: #{from_to[:to].nil? ? "Empty" : from_to[:to]}"
14
- br/
@@ -1,23 +0,0 @@
1
- <% updated_relations.each do |relation| %>
2
- <b class="text-secondary"><%= update_relation_class(relation) %></b>
3
- <br>
4
- <% if relation[:previous_attrs].present? %>
5
- <i>From:</i>
6
- <br>
7
- <%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation[:previous_attrs][:attrs] } %>
8
- <% else %>
9
- <i>From:</i>
10
- <br>
11
- Empty
12
- <br>
13
- <% end %>
14
- <% if relation[:current_attrs].present? %>
15
- <i>To:</i>
16
- <br>
17
- <%= render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation[:current_attrs][:attrs] } %>
18
- <% else %>
19
- <i>To:</i>
20
- <br>
21
- Empty
22
- <% end %>
23
- <% end %>
@@ -1,21 +0,0 @@
1
- - updated_relations.each do |relation|
2
- b.text-secondary = update_relation_class(relation)
3
- br/
4
- - if relation[:previous_attrs].present?
5
- i From:
6
- br/
7
- = render partial:'loggable_activity/templates/shared/list_attrs', locals: {attrs: relation[:previous_attrs][:attrs] }
8
- - else
9
- i From:
10
- br/
11
- |Empty
12
- br
13
- - if relation[:current_attrs].present?
14
- i To:
15
- br/
16
- = render partial: 'loggable_activity/templates/shared/list_attrs', locals: { attrs: relation[:current_attrs][:attrs] }
17
- - else
18
- i To:
19
- br/
20
- |Empty
21
-
@@ -1,153 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module LoggableActivity
4
- # This module is responsible for building payloads used in loggable activities.
5
- module PayloadsBuilder
6
- # Builds payloads for the loggable activity.
7
- #
8
- # Example:
9
- # build_payloads
10
- #
11
- # Returns:
12
- # #<LoggableActivity::Payload:0x0000000109658718> {
13
- # :id => 129,
14
- # :record_type => "Demo::Club",
15
- # :record_id => 4,
16
- # :encrypted_attrs => {
17
- # "name" => "z/jigjcm3Fb89L7QT8XiNhvVgjtRXKkmg/xohR6wIc0=\n"
18
- # },
19
- # :payload_type => "current_association",
20
- # :data_owner => nil,
21
- # :activity_id => 50,
22
- # :created_at => Wed, 14 Feb 2024 13:21:13.964339000 UTC +00:00,
23
- # :updated_at => Wed, 14 Feb 2024 13:21:13.964339000 UTC +00:00
24
- # }
25
- #
26
- def build_payloads
27
- build_primary_payload
28
- self.class.relations.each do |relation_config|
29
- build_relation_payload(relation_config)
30
- end
31
- @payloads
32
- end
33
-
34
- private
35
-
36
- # Builds the primary payload.
37
- def build_primary_payload
38
- encrypted_attrs = encrypt_attrs(attributes, self.class.loggable_attrs, primary_encryption_key)
39
- @payloads << LoggableActivity::Payload.new(
40
- record: @record,
41
- payload_type: 'primary_payload',
42
- encrypted_attrs:,
43
- data_owner: true,
44
- route: self.class.route
45
- )
46
- end
47
-
48
- # Builds the payload for destroyed records.
49
- def build_destroy_payload
50
- encrypted_attrs = encrypt_attrs(attributes, self.class.loggable_attrs, primary_encryption_key)
51
- encrypted_attrs.transform_values! { '*** DELETED ***' }
52
- @payloads << LoggableActivity::Payload.new(
53
- record: @record,
54
- payload_type: 'primary_payload',
55
- encrypted_attrs:,
56
- data_owner: true,
57
- route: nil
58
- )
59
- end
60
-
61
- # Builds payloads for relations
62
- #
63
- # @param relation_config [Hash] The configuration of the relation.
64
- def build_relation_payload(relation_config)
65
- relation_config.each_key do |key|
66
- case key
67
- when 'belongs_to'
68
- build_payload(relation_config, 'belongs_to')
69
- when 'has_one'
70
- build_payload(relation_config, 'has_one')
71
- when 'has_many'
72
- build_has_many_payloads(relation_config, 'has_many')
73
- end
74
- end
75
- end
76
-
77
- # Builds the payload for a specific relation.
78
- #
79
- # @param relation_config [Hash] The configuration of the relation.
80
- # @param relation_type [String] The type of the relation.
81
- def build_payload(relation_config, relation_type)
82
- associated_record = send(relation_config[relation_type])
83
- return nil if associated_record.nil?
84
-
85
- build_associated_payload(associated_record, relation_config)
86
- end
87
-
88
- # Builds payloads for has_many relations.
89
- def build_has_many_payloads(relation_config, relation_type)
90
- associated_records = send(relation_config[relation_type])
91
- return nil if associated_records.empty?
92
-
93
- associated_records.each do |associated_record|
94
- build_associated_payload(associated_record, relation_config)
95
- end
96
- end
97
-
98
- # Builds the payload for an associated record.
99
- def build_associated_payload(associated_record, relation_config)
100
- associated_loggable_attrs = relation_config['loggable_attrs']
101
- encryption_key = associated_record_encryption_key(associated_record, relation_config['data_owner'])
102
- encrypted_attrs =
103
- encrypt_attrs(
104
- associated_record.attributes,
105
- associated_loggable_attrs,
106
- encryption_key.key
107
- )
108
-
109
- @payloads << LoggableActivity::Payload.new(
110
- record: associated_record,
111
- encrypted_attrs:,
112
- payload_type: 'current_association',
113
- data_owner: relation_config['data_owner'],
114
- route: relation_config['route']
115
- )
116
- end
117
-
118
- # Retrieves the encryption key for the associated record.
119
- #
120
- # @param associated_record [ActiveRecord::Base] The associated record.
121
- # @param data_owner [Boolean] Whether the associated record is the owner of the data.
122
- # @return [LoggableActivity::EncryptionKey] The encryption key for the associated record.
123
- def associated_record_encryption_key(associated_record, data_owner)
124
- if data_owner
125
- LoggableActivity::EncryptionKey.for_record(associated_record, LoggableActivity::EncryptionKey.for_record(self))
126
- else
127
- LoggableActivity::EncryptionKey.for_record(associated_record)
128
- end
129
- end
130
-
131
- # Encrypts attributes.
132
- #
133
- # @param attrs [Hash] The attributes to be encrypted.
134
- # @param loggable_attrs [Array<String>] The loggable attributes.
135
- # @param encryption_key [String] The encryption key.
136
- # @return [Hash] The encrypted attributes.
137
- def encrypt_attrs(attrs, loggable_attrs, encryption_key)
138
- attrs = attrs.slice(*loggable_attrs)
139
- encrypt_attr(attrs, encryption_key)
140
- end
141
-
142
- # Encrypts a single attribute.
143
- #
144
- # @param attrs [Hash] The attributes to be encrypted.
145
- # @param encryption_key [String] The encryption key.
146
- # @return [Hash] The encrypted attributes.
147
- def encrypt_attr(attrs, encryption_key)
148
- attrs.each do |key, value|
149
- attrs[key] = LoggableActivity::Encryption.encrypt(value, encryption_key)
150
- end
151
- end
152
- end
153
- end
@@ -1,127 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module LoggableActivity
4
- # This module is responsible for building update payloads used in loggable activities.
5
- module UpdatePayloadsBuilder
6
- # Builds payloads for an activity update event.
7
- def build_update_payloads
8
- @update_payloads = []
9
-
10
- previous_values, current_values = primary_update_attrs
11
- build_primary_update_payload(previous_values, current_values)
12
-
13
- self.class.relations.each do |relation_config|
14
- build_update_relation_payloads(relation_config)
15
- end
16
- @update_payloads
17
- end
18
-
19
- private
20
-
21
- # Fetch the previous and current values of the primary record.
22
- def primary_update_attrs
23
- previous_values = saved_changes.transform_values(&:first)
24
- current_values = saved_changes.transform_values(&:last)
25
-
26
- [previous_values, current_values]
27
- end
28
-
29
- # Builds the primary update payload.
30
- def build_primary_update_payload(previous_values, current_values)
31
- return if previous_values == current_values
32
-
33
- encrypted_update_attrs = encrypted_update_attrs(previous_values, current_values)
34
- @update_payloads << LoggableActivity::Payload.new(
35
- record: @record,
36
- payload_type: 'update_payload',
37
- encrypted_attrs: encrypted_update_attrs,
38
- route: self.class.route
39
- )
40
- end
41
-
42
- # Returns the encrypted attributes for the update payload.
43
- def encrypted_update_attrs(previous_values, current_values)
44
- changes = []
45
- changed_attrs = previous_values.slice(*self.class.loggable_attrs)
46
- changed_attrs.each do |key, from_value|
47
- from = LoggableActivity::Encryption.encrypt(from_value, primary_encryption_key)
48
- to_value = current_values[key]
49
- to = LoggableActivity::Encryption.encrypt(to_value, primary_encryption_key)
50
- changes << { key => { from:, to: } }
51
- end
52
- { changes: }
53
- end
54
-
55
- # Builds update payloads for relations.
56
- def build_update_relation_payloads(relation_config)
57
- relation_config.each_key do |key|
58
- case key
59
- when 'belongs_to'
60
- build_relation_update_for_belongs_to(relation_config)
61
- when 'has_one'
62
- build_relation_update_for_has_one(relation_config)
63
- when 'has_many'
64
- build_relation_update_for_has_many(relation_config)
65
- end
66
- end
67
- end
68
-
69
- # Builds the update payload for a has_many relation.
70
- def build_relation_update_for_has_many(relation_config)
71
- # NOTE: This method is not implemented yet.
72
- # It requires that there is a form where it is possible to change
73
- # the related records. This is not implemented yet. in the Demo app
74
- # puts relation_config['has_many']
75
- end
76
-
77
- # Builds the update payload for a has_one relation.
78
- def build_relation_update_for_has_one(relation_config)
79
- # NOTE: This method is not implemented yet.
80
- # It requires that there is a form where it is possible to change
81
- # the related records. This is not implemented yet. in the Demo app
82
- # puts relation_config['has_one']
83
- end
84
-
85
- # Builds the update payload for a belongs_to relation.
86
- def build_relation_update_for_belongs_to(relation_config)
87
- relation_id = "#{relation_config['belongs_to']}_id"
88
- model_class_name = relation_config['model']
89
- model_class = model_class_name.constantize
90
-
91
- return unless saved_changes.include?(relation_id)
92
-
93
- relation_id_changes = saved_changes[relation_id]
94
- previous_relation_id, current_relation_id = relation_id_changes
95
-
96
- [previous_relation_id, current_relation_id].each_with_index do |id, index|
97
- relation_record = id ? model_class.find_by(id:) : nil
98
- next unless relation_record
99
-
100
- payload_type = index.zero? ? 'previous_association' : 'current_association'
101
- build_relation_update_payload(
102
- relation_config,
103
- relation_record,
104
- payload_type
105
- )
106
- end
107
- end
108
-
109
- # Builds the update payload for a relation.
110
- def build_relation_update_payload(relation_config, record, payload_type)
111
- encryption_key = LoggableActivity::EncryptionKey.for_record(record)&.key
112
- encrypted_attrs = relation_encrypted_attrs(record.attributes, relation_config['loggable_attrs'], encryption_key)
113
-
114
- @update_payloads << LoggableActivity::Payload.new(
115
- record:,
116
- encrypted_attrs:,
117
- payload_type:,
118
- route: relation_config['route']
119
- )
120
- end
121
-
122
- # Returns the encrypted attributes for a relation.
123
- def relation_encrypted_attrs(attrs, loggable_attrs, encryption_key)
124
- encrypt_attrs(attrs, loggable_attrs, encryption_key)
125
- end
126
- end
127
- end