effective_trash 0.2.0 → 0.2.1
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
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b5861ff673da253d2c1b764bad5f96c21c4ede0f
|
4
|
+
data.tar.gz: 619b6e251bc29e258dfb2daddcb7e022a7efc4bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0cc1f9d9d136367ca6777e4f81733a4bc97e6518efee7f8186292a4eb106ae95c4f4f931350485f2d40eeb4369040904076316db05c9910cbc4016feaf267b8b
|
7
|
+
data.tar.gz: 198377e4829662be812a8bdbb21eafd8b4e8432954a2311347afc45eb64d38ec7e6f926331d3efb89217e4df695d9f3fea898ce668e649884d9af37878aaa9e3
|
@@ -23,7 +23,7 @@ module ActsAsTrashable
|
|
23
23
|
trashed_to_s: to_s,
|
24
24
|
trashed_extra: (trashed_extra if respond_to?(:trashed_extra)),
|
25
25
|
|
26
|
-
details: EffectiveTrash::
|
26
|
+
details: EffectiveTrash::ActiveRecordSerializer.new(self, acts_as_trashable_options).attributes
|
27
27
|
).save!
|
28
28
|
end
|
29
29
|
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module EffectiveTrash
|
2
|
+
class ActiveRecordSerializer
|
3
|
+
attr_accessor :resource, :options
|
4
|
+
|
5
|
+
def initialize(resource, options = {})
|
6
|
+
raise ArgumentError.new('options must be a Hash') unless options.kind_of?(Hash)
|
7
|
+
|
8
|
+
@resource = resource
|
9
|
+
@options = options
|
10
|
+
end
|
11
|
+
|
12
|
+
def attributes
|
13
|
+
attributes = { attributes: resource.attributes }
|
14
|
+
|
15
|
+
# Collect to_s representations of all belongs_to associations
|
16
|
+
(resource.class.try(:reflect_on_all_associations, :belongs_to) || []).each do |association|
|
17
|
+
attributes[association.name] = resource.send(association.name).to_s.presence
|
18
|
+
end
|
19
|
+
|
20
|
+
# Collect to_s representations for all has_one associations
|
21
|
+
(resource.class.try(:reflect_on_all_associations, :has_one) || []).each do |association|
|
22
|
+
next if association.name == :trash && resource.respond_to?(:acts_as_trashable_options) # We skip our own association
|
23
|
+
attributes[association.name] = resource.send(association.name).to_s.presence
|
24
|
+
end
|
25
|
+
|
26
|
+
# Collects attributes for all accepts_as_nested_parameters has_many associations
|
27
|
+
(resource.class.try(:reflect_on_all_autosave_associations) || []).each do |association|
|
28
|
+
attributes[association.name] = {}
|
29
|
+
|
30
|
+
Array(resource.send(association.name)).each_with_index do |child, index|
|
31
|
+
attributes[association.name][index+1] = ActiveRecordLogger.new(child, options).attributes
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attributes.delete_if { |k, v| v.blank? }
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
# TODO: Make this work better with nested objects
|
41
|
+
def applicable(attributes)
|
42
|
+
atts = if options[:only].present?
|
43
|
+
attributes.slice(*options[:only])
|
44
|
+
elsif options[:except].present?
|
45
|
+
attributes.except(*options[:except])
|
46
|
+
else
|
47
|
+
attributes.except(:updated_at, :created_at)
|
48
|
+
end
|
49
|
+
|
50
|
+
(options[:additionally] || []).each do |attribute|
|
51
|
+
value = (resource.send(attribute) rescue :effective_trash_nope)
|
52
|
+
next if attributes[attribute].present? || value == :effective_trash_nope
|
53
|
+
|
54
|
+
atts[attribute] = value
|
55
|
+
end
|
56
|
+
|
57
|
+
atts
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_trash
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -106,7 +106,7 @@ files:
|
|
106
106
|
- config/routes.rb
|
107
107
|
- db/migrate/01_create_effective_trash.rb.erb
|
108
108
|
- lib/effective_trash.rb
|
109
|
-
- lib/effective_trash/
|
109
|
+
- lib/effective_trash/active_record_serializer.rb
|
110
110
|
- lib/effective_trash/engine.rb
|
111
111
|
- lib/effective_trash/set_current_user.rb
|
112
112
|
- lib/effective_trash/version.rb
|
@@ -1,160 +0,0 @@
|
|
1
|
-
module EffectiveTrash
|
2
|
-
class ActiveRecordLogger
|
3
|
-
attr_accessor :resource, :logger, :depth, :options
|
4
|
-
|
5
|
-
BLANK = "''"
|
6
|
-
|
7
|
-
def initialize(resource, options = {})
|
8
|
-
raise ArgumentError.new('options must be a Hash') unless options.kind_of?(Hash)
|
9
|
-
|
10
|
-
@resource = resource
|
11
|
-
@logger = options.delete(:logger) || resource
|
12
|
-
@depth = options.delete(:depth) || 0
|
13
|
-
@options = options
|
14
|
-
|
15
|
-
unless @logger.respond_to?(:logged_changes) || @logger.respond_to?(:trash)
|
16
|
-
raise ArgumentError.new('logger must respond to logged_changes or trash')
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# execute! is called when we recurse, otherwise the following methods are best called individually
|
21
|
-
def execute!
|
22
|
-
if resource.new_record?
|
23
|
-
created!
|
24
|
-
elsif resource.marked_for_destruction?
|
25
|
-
destroyed!
|
26
|
-
else
|
27
|
-
changed!
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# before_destroy
|
32
|
-
def trashed!
|
33
|
-
log_trash((resource.to_s rescue ''), details: applicable(attributes))
|
34
|
-
end
|
35
|
-
|
36
|
-
# before_destroy
|
37
|
-
def destroyed!
|
38
|
-
log('Deleted', details: applicable(attributes))
|
39
|
-
end
|
40
|
-
|
41
|
-
# after_commit
|
42
|
-
def created!
|
43
|
-
log('Created', details: applicable(attributes))
|
44
|
-
end
|
45
|
-
|
46
|
-
# after_commit
|
47
|
-
def updated!
|
48
|
-
log('Updated', details: applicable(attributes))
|
49
|
-
end
|
50
|
-
|
51
|
-
# before_save
|
52
|
-
def changed!
|
53
|
-
applicable(changes).each do |attribute, (before, after)|
|
54
|
-
if resource.respond_to?(:log_changes_formatted_value)
|
55
|
-
before = resource.log_changes_formatted_value(attribute, before) || before
|
56
|
-
after = resource.log_changes_formatted_value(attribute, after) || after
|
57
|
-
end
|
58
|
-
|
59
|
-
attribute = if resource.respond_to?(:log_changes_formatted_attribute)
|
60
|
-
resource.log_changes_formatted_attribute(attribute)
|
61
|
-
end || attribute.titleize
|
62
|
-
|
63
|
-
if after.present?
|
64
|
-
log("#{attribute} changed from #{before.presence || BLANK} to #{after.presence || BLANK}", details: { attribute: attribute, before: before, after: after })
|
65
|
-
else
|
66
|
-
log("#{attribute} set to #{before || BLANK}", details: { attribute: attribute, value: before })
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Log changes on all accepts_as_nested_parameters has_many associations
|
71
|
-
(resource.class.try(:reflect_on_all_autosave_associations) || []).each do |association|
|
72
|
-
child_name = association.name.to_s.singularize.titleize
|
73
|
-
|
74
|
-
Array(resource.send(association.name)).each_with_index do |child, index|
|
75
|
-
ActiveRecordLogger.new(child, options.merge(logger: logger, depth: (depth + 1), prefix: "#{child_name} ##{index+1}: ")).execute!
|
76
|
-
end
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
def attributes
|
81
|
-
attributes = { attributes: resource.attributes }
|
82
|
-
|
83
|
-
# Collect to_s representations of all belongs_to associations
|
84
|
-
(resource.class.try(:reflect_on_all_associations, :belongs_to) || []).each do |association|
|
85
|
-
attributes[association.name] = resource.send(association.name).to_s.presence || 'nil'
|
86
|
-
end
|
87
|
-
|
88
|
-
# Collect to_s representations for all has_one associations
|
89
|
-
(resource.class.try(:reflect_on_all_associations, :has_one) || []).each do |association|
|
90
|
-
next if association.name == :trash && resource.respond_to?(:acts_as_trashable_options) # We skip our own association
|
91
|
-
attributes[association.name] = resource.send(association.name).to_s.presence || 'nil'
|
92
|
-
end
|
93
|
-
|
94
|
-
# Collects attributes for all accepts_as_nested_parameters has_many associations
|
95
|
-
(resource.class.try(:reflect_on_all_autosave_associations) || []).each do |association|
|
96
|
-
attributes[association.name] = {}
|
97
|
-
|
98
|
-
Array(resource.send(association.name)).each_with_index do |child, index|
|
99
|
-
attributes[association.name][index+1] = ActiveRecordLogger.new(child, options.merge(logger: logger)).attributes
|
100
|
-
end
|
101
|
-
end
|
102
|
-
|
103
|
-
attributes
|
104
|
-
end
|
105
|
-
|
106
|
-
def changes
|
107
|
-
changes = resource.changes
|
108
|
-
|
109
|
-
# Log to_s changes on all belongs_to associations
|
110
|
-
(resource.class.try(:reflect_on_all_associations, :belongs_to) || []).each do |association|
|
111
|
-
if (change = changes.delete(association.foreign_key)).present?
|
112
|
-
changes[association.name] = [association.klass.find_by_id(change.first), resource.send(association.name)]
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
changes
|
117
|
-
end
|
118
|
-
|
119
|
-
private
|
120
|
-
|
121
|
-
def log(message, details: {})
|
122
|
-
logger.logged_changes.build(
|
123
|
-
user: EffectiveTrash.current_user,
|
124
|
-
status: EffectiveTrash.log_changes_status,
|
125
|
-
message: "#{"\t" * depth}#{options[:prefix]}#{message}",
|
126
|
-
details: details
|
127
|
-
).tap { |log| log.save }
|
128
|
-
end
|
129
|
-
|
130
|
-
def log_trash(message, details: {})
|
131
|
-
logger.build_trash(
|
132
|
-
user: EffectiveTrash.current_user,
|
133
|
-
status: EffectiveTrash.trashable_status,
|
134
|
-
message: "#{"\t" * depth}#{options[:prefix]}#{message}",
|
135
|
-
details: details
|
136
|
-
).tap { |log| log.save }
|
137
|
-
end
|
138
|
-
|
139
|
-
# TODO: Make this work better with nested objects
|
140
|
-
def applicable(attributes)
|
141
|
-
atts = if options[:only].present?
|
142
|
-
attributes.slice(*options[:only])
|
143
|
-
elsif options[:except].present?
|
144
|
-
attributes.except(*options[:except])
|
145
|
-
else
|
146
|
-
attributes.except(:updated_at, :created_at)
|
147
|
-
end
|
148
|
-
|
149
|
-
(options[:additionally] || []).each do |attribute|
|
150
|
-
value = (resource.send(attribute) rescue :effective_trash_nope)
|
151
|
-
next if attributes[attribute].present? || value == :effective_trash_nope
|
152
|
-
|
153
|
-
atts[attribute] = value
|
154
|
-
end
|
155
|
-
|
156
|
-
atts
|
157
|
-
end
|
158
|
-
|
159
|
-
end
|
160
|
-
end
|