audited-serialize 0.0.1 → 0.0.2

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: d48590492cd52769b859d9fe98d28d8bdaffa3ba106cf31c600799d3302efa2b
4
- data.tar.gz: 98c8038df1e219d2162bfd4cedb6b5bf2a6fe74abbf1dbb0c987673cb36f1239
3
+ metadata.gz: aa2ae142361013574ee5100ed3edf7da72ffa6a04758a894dfab763a3c37b82e
4
+ data.tar.gz: cee3114d051d34099d11d9f9f402c7dffa8a0d61c813d472a11f73a5afafabed
5
5
  SHA512:
6
- metadata.gz: 6a90a9a8bbc607becefdaa2441d94916970af899cb20cbe694c7d24db6cca6fbf1f78de0fedf376baaad2b220fb6eed634ddb8a04ec515afb06aea055de7838f
7
- data.tar.gz: 4552d6ee7304c6e0561144f27ea1ec32b9b9647be8822b268179956d91295e3b872026f217a2fe33a0a670958412de0681704ff8e61f3d7fa1a0048fdc724beb
6
+ metadata.gz: 929cd4a6b8a55c730db3d644755f23cc33bb27f5e39553bd54cf67b8d6bcea0fe80c6b84eb412d7f4c7e3c03851493022d40c3fb177e908c5fb5ea919d6f4d35
7
+ data.tar.gz: f79cac8c70bddc12ee980194d557d9fb1f7e8d04c45d5083fdecd996015e3df1e9c31f7ed090866560263182251546675380a1050895ec9f8a4229668b2b4eca
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # Audited Serialize
2
+ [![Gem Version](https://badge.fury.io/rb/audited-serialize.svg)](https://badge.fury.io/rb/audited-serialize)
2
3
 
3
- Гем для сериализации аудит-логов на базе Audited
4
+ Гем для сериализации аудит-логов на базе Audited.
4
5
 
5
6
  ## Установка
6
7
 
@@ -15,3 +16,40 @@ gem 'audited-serialize'
15
16
  ```
16
17
  bundle
17
18
  ```
19
+
20
+ ## Использование
21
+
22
+ Для вызова сериализованного списка изменений вызовите метод `.changes_list` на экземпляре audit-класса (по умолчанию - `Audited::Audit`)
23
+
24
+ ```
25
+ audit = Audited::Audit.first
26
+ audit.changes_list
27
+ ```
28
+
29
+ ## Конфигурация
30
+
31
+ Изменение настроек сериализации осуществляется путем редактирования стандартного файла конфигурации `Audited`
32
+
33
+ ```
34
+ # config/initializers/audited.rb
35
+
36
+ Audited.config do |config|
37
+
38
+ end
39
+ ```
40
+
41
+ ### Исключения
42
+
43
+ Для добавления исключений для полей сущностей, которые не будут отображаться в списке добавьте в конфиг `serialization_exceptions`.
44
+
45
+ ```
46
+ # config/initializers/audited.rb
47
+
48
+ Audited.config do |config|
49
+
50
+ config.serialization_exceptions = {
51
+ 'User' => ['role']
52
+ }
53
+
54
+ end
55
+ ```
@@ -0,0 +1,9 @@
1
+ require 'audited/serialization'
2
+
3
+ module Audited
4
+ class Audit < ::ActiveRecord::Base
5
+
6
+ include Audited::Serialization
7
+
8
+ end
9
+ end
@@ -0,0 +1,185 @@
1
+ module Audited
2
+ module Serialization
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ def changes_list
7
+ model = auditable_type.constantize
8
+ columns_hash = model.columns_hash
9
+ @reflections = model.reflections.to_h { |_relation, reflection| [reflection.foreign_key, reflection.klass] }
10
+
11
+ audited_changes.map do |column, value|
12
+ @column = column
13
+
14
+ # пропускаем, если колонка в списке исключений
15
+ next if Audited.serialization_exceptions[auditable_type]&.include?(@column)
16
+
17
+ # поле таблицы БД
18
+ @db_column = columns_hash[column]
19
+
20
+ # русскоязычное название поля
21
+ @field = @db_column.comment
22
+
23
+ if action == 'update' && value.is_a?(Array)
24
+ # значения, измененные во время редактирования
25
+ @initial, @changed = value
26
+ else
27
+ # значения, заданные во время создания
28
+ @changed = value
29
+ end
30
+
31
+ if related_record_changed?
32
+ related_record_changes
33
+ elsif object?
34
+ json_changes
35
+ elsif array?
36
+ array_changes
37
+ elsif password?
38
+ password_changes
39
+ elsif date?
40
+ date_changes
41
+ elsif datetime?
42
+ datetime_changes
43
+ elsif boolean?
44
+ boolean_changes
45
+ elsif enum_changes?
46
+ enum_changes
47
+ else
48
+ common_column_changes
49
+ end
50
+
51
+ next if @from.blank? && @to.blank?
52
+
53
+ {
54
+ field: @field,
55
+ from: @from,
56
+ to: @to
57
+ }
58
+ end.compact
59
+ end
60
+
61
+ private
62
+
63
+ def related_record_changed?
64
+ @reflections[@column].present?
65
+ end
66
+
67
+ def object?
68
+ @initial.is_a?(Hash) || @changed.is_a?(Hash)
69
+ end
70
+
71
+ def array?
72
+ @initial.is_a?(Array) || @changed.is_a?(Array)
73
+ end
74
+
75
+ def password?
76
+ @column == 'encrypted_password'
77
+ end
78
+
79
+ def datetime?
80
+ @initial&.to_date&.acts_like?(:date) && @initial.include?(':') rescue false
81
+ @changed&.to_date&.acts_like?(:date) && @changed.include?(':') rescue false
82
+ end
83
+
84
+ def date?
85
+ @initial&.to_date&.acts_like?(:date) && @initial.to_s.include?('-') && @initial.to_s.exclude?(':') rescue false
86
+ @changed&.to_date&.acts_like?(:date) && @changed.to_s.include?('-') && @changed.to_s.exclude?(':') rescue false
87
+ end
88
+
89
+ def boolean?
90
+ bool_classes = [TrueClass, FalseClass]
91
+
92
+ bool_classes.include?(@initial.class) || bool_classes.include?(@changed.class)
93
+ end
94
+
95
+ def enum_changes?
96
+ @db_column.type == :enum
97
+ end
98
+
99
+ def related_record_changes
100
+ # модель связанной сущности от колонки
101
+ related_model = @reflections[@column]
102
+
103
+ # заданные/измененные значения
104
+ @from = related_record_value(related_model, @initial)
105
+ @to = related_record_value(related_model, @changed)
106
+ end
107
+
108
+ def related_record_value(related_model, value)
109
+ if value
110
+ record = related_model.find_by(id: value)
111
+ auditing_title(record) || "Запись ##{value}"
112
+ else
113
+ ''
114
+ end
115
+ end
116
+
117
+ def auditing_title(record)
118
+ return unless record
119
+
120
+ if record.is_a?(House)
121
+ record.number
122
+ elsif record.klass.column_names.include?('name')
123
+ record.name
124
+ else
125
+ "##{record.id}"
126
+ end
127
+ end
128
+
129
+ def enum_changes
130
+ enum_type = @db_column.sql_type
131
+ values = I18n.t("enums.#{enum_type}").stringify_keys
132
+
133
+ @from = values[@initial]
134
+ @to = values[@changed]
135
+ end
136
+
137
+ def json_changes
138
+ # удаление дубликатов ключей/значений
139
+ initial = (@initial.to_a - @changed.to_a).to_h
140
+ changed = (@changed.to_a - @initial.to_a).to_h
141
+
142
+ @from = initial.map { |k, v| "#{k.humanize}: #{v}" }
143
+ @to = changed.map { |k, v| "#{k.humanize}: #{v}" }
144
+ end
145
+
146
+ def array_changes
147
+ @from = @initial&.join(', ')
148
+ @to = @changed&.join(', ')
149
+ end
150
+
151
+ def password_changes
152
+ @field = 'Пароль'
153
+ @from = nil
154
+ @to = '<новый>'
155
+ end
156
+
157
+ def date_changes
158
+ @from = Date.parse(@initial).strftime('%d.%m.%Y') if @initial.present?
159
+ @to = Date.parse(@changed).strftime('%d.%m.%Y') if @changed.present?
160
+ end
161
+
162
+ def datetime_changes
163
+ if @initial.present?
164
+ @from = DateTime.parse(@initial).in_time_zone('Europe/Moscow').strftime('%d.%m.%Y %H:%M')
165
+ end
166
+
167
+ if @changed.present?
168
+ @to = DateTime.parse(@changed).in_time_zone('Europe/Moscow').strftime('%d.%m.%Y %H:%M')
169
+ end
170
+ end
171
+
172
+ def boolean_changes
173
+ values = { true => 'Да', false => 'Нет' }
174
+
175
+ @from = values[@initial]
176
+ @to = values[@changed]
177
+ end
178
+
179
+ def common_column_changes
180
+ @from = @initial
181
+ @to = @changed
182
+ end
183
+
184
+ end
185
+ end
@@ -1 +1 @@
1
- require 'audited_serialize'
1
+ require 'audited_serialize'
@@ -0,0 +1,11 @@
1
+ module Audited
2
+
3
+ class << self
4
+
5
+ attr_accessor :serialization_exceptions
6
+
7
+ end
8
+
9
+ @serialization_exceptions = {}
10
+
11
+ end
@@ -1,2 +1,5 @@
1
+ require 'audited_config'
2
+ require 'audited/original_audit'
3
+
1
4
  module AuditedSerialize
2
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: audited-serialize
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Павел Бабин
@@ -32,6 +32,9 @@ extra_rdoc_files: []
32
32
  files:
33
33
  - README.md
34
34
  - lib/audited-serialize.rb
35
+ - lib/audited/original_audit.rb
36
+ - lib/audited/serialization.rb
37
+ - lib/audited_config.rb
35
38
  - lib/audited_serialize.rb
36
39
  homepage:
37
40
  licenses: