Skip to content

Commit 8b42f6e

Browse files
committed
git-er-done
1 parent b187060 commit 8b42f6e

File tree

6 files changed

+172
-6
lines changed

6 files changed

+172
-6
lines changed

.rubocop.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ Layout/MultilineOperationIndentation:
4545
Layout/SpaceBeforeComment:
4646
Enabled: false
4747

48+
Layout/SpaceBeforeBlockBraces:
49+
Enabled: false
50+
51+
Layout/SpaceAroundBlockParameters:
52+
Enabled: false
53+
4854
LeadingCommentSpace:
4955
Enabled: false
5056

@@ -158,6 +164,9 @@ Style/LineEndConcatenation:
158164
Style/RedundantReturn:
159165
Enabled: false
160166

167+
Style/Proc:
168+
Enabled: false
169+
161170
# The Ruby Style Guide does not prescribe a particular quote character, only
162171
# that a project should pick one and be consistent. The decision has no
163172
# performance implications. Double quotes are slightly easier to read.

Rakefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,17 @@ task :autocorrect do
4545
'Style/EmptyMethod',
4646
'Style/TrailingCommaInArguments',
4747
]
48-
`bundle exec rubocop --auto-correct --only #{rules.join(' --only ')}`
48+
49+
rules.each do |rule|
50+
`bundle exec rubocop --auto-correct --only #{rule}`
51+
end
52+
53+
Rake::Task['rubocop'].invoke
4954
end
5055

5156
require "rubocop/rake_task"
5257
RuboCop::RakeTask.new
5358

59+
### TODO: Allow rubocop to fail, but still continue
5460
desc "Default: run all available test suites"
55-
task default: %i[autocorrect rubocop prepare test spec]
61+
task default: %i[rubocop prepare test spec]

lib/paper_trail_association_tracking.rb

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ def self.gem_version
1616
end
1717

1818
module PaperTrail
19-
#class << self
20-
# prepend ::PaperTrailAssociationTracking::PaperTrail
21-
#end
19+
class << self
20+
prepend ::PaperTrailAssociationTracking::PaperTrail
21+
end
2222

2323
class Config
2424
prepend ::PaperTrailAssociationTracking::Config
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# frozen_string_literal: true
2+
3+
module PaperTrailAssociationTracking
4+
module PaperTrail
5+
def transaction?
6+
::ActiveRecord::Base.connection.open_transactions.positive?
7+
end
8+
end
9+
end

lib/paper_trail_association_tracking/record_trail.rb

Lines changed: 123 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,130 @@
11
# frozen_string_literal: true
22

33
module PaperTrailAssociationTracking
4-
# Represents the "paper trail" for a single record.
54
class RecordTrail
5+
# Utility method for reifying. Anything executed inside the block will
6+
# appear like a new record.
7+
#
8+
# > .. as best as I can tell, the purpose of
9+
# > appear_as_new_record was to attempt to prevent the callbacks in
10+
# > AutosaveAssociation (which is the module responsible for persisting
11+
# > foreign key changes earlier than most people want most of the time
12+
# > because backwards compatibility or the maintainer hates himself or
13+
# > something) from running. By also stubbing out persisted? we can
14+
# > actually prevent those. A more stable option might be to use suppress
15+
# > instead, similar to the other branch in reify_has_one.
16+
# > -Sean Griffin (https://github.com/paper-trail-gem/paper_trail/pull/899)
17+
#
18+
# @api private
19+
# def appear_as_new_record
20+
# @record.instance_eval {
21+
# alias :old_new_record? :new_record?
22+
# alias :new_record? :present?
23+
# alias :old_persisted? :persisted?
24+
# alias :persisted? :nil?
25+
# }
26+
# yield
27+
# @record.instance_eval {
28+
# alias :new_record? :old_new_record?
29+
# alias :persisted? :old_persisted?
30+
# }
31+
# end
32+
33+
def record_create
34+
@in_after_callback = true
35+
return unless enabled?
36+
versions_assoc = @record.send(@record.class.versions_association_name)
37+
version = versions_assoc.create! data_for_create
38+
update_transaction_id(version)
39+
save_associations(version)
40+
ensure
41+
@in_after_callback = false
42+
end
43+
44+
def data_for_create
45+
data = super
46+
add_transaction_id_to(data)
47+
data
48+
end
49+
50+
def record_destroy(recording_order)
51+
@in_after_callback = recording_order == "after"
52+
if enabled? && !@record.new_record?
53+
version = @record.class.paper_trail.version_class.create(data_for_destroy)
54+
if version.errors.any?
55+
log_version_errors(version, :destroy)
56+
else
57+
@record.send("#{@record.class.version_association_name}=", version)
58+
@record.send(@record.class.versions_association_name).reset
59+
update_transaction_id(version)
60+
save_associations(version)
61+
end
62+
end
63+
ensure
64+
@in_after_callback = false
65+
end
66+
67+
def data_for_destroy
68+
data = super
69+
add_transaction_id_to(data)
70+
data
71+
end
72+
73+
# Returns a boolean indicating whether to store serialized version diffs
74+
# in the `object_changes` column of the version record.
75+
# @api private
76+
def record_object_changes?
77+
@record.paper_trail_options[:save_changes] &&
78+
@record.class.paper_trail.version_class.column_names.include?("object_changes")
79+
end
80+
81+
def record_update(force:, in_after_callback:, is_touch:)
82+
@in_after_callback = in_after_callback
83+
if enabled? && (force || changed_notably?)
84+
versions_assoc = @record.send(@record.class.versions_association_name)
85+
version = versions_assoc.create(data_for_update(is_touch))
86+
if version.errors.any?
87+
log_version_errors(version, :update)
88+
else
89+
update_transaction_id(version)
90+
save_associations(version)
91+
end
92+
end
93+
ensure
94+
@in_after_callback = false
95+
end
96+
97+
# Used during `record_update`, returns a hash of data suitable for an AR
98+
# `create`. That is, all the attributes of the nascent `Version` record.
99+
#
100+
# @api private
101+
def data_for_update(is_touch)
102+
data = super
103+
add_transaction_id_to(data)
104+
data
105+
end
106+
107+
# @api private
108+
def record_update_columns(changes)
109+
return unless enabled?
110+
versions_assoc = @record.send(@record.class.versions_association_name)
111+
version = versions_assoc.create(data_for_update_columns(changes))
112+
if version.errors.any?
113+
log_version_errors(version, :update)
114+
else
115+
update_transaction_id(version)
116+
save_associations(version)
117+
end
118+
end
119+
120+
# Returns data for record_update_columns
121+
# @api private
122+
def data_for_update_columns(changes)
123+
data = super
124+
add_transaction_id_to(data)
125+
data
126+
end
127+
6128
# Saves associations if the join table for `VersionAssociation` exists.
7129
def save_associations(version)
8130
return unless PaperTrail.config.track_associations?
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# frozen_string_literal: true
2+
3+
module PaperTrailAssociationTracking
4+
module Request
5+
# @api private
6+
def self.clear_transaction_id
7+
self.transaction_id = nil
8+
end
9+
10+
# @api private
11+
def self.transaction_id
12+
store[:transaction_id]
13+
end
14+
15+
# @api private
16+
def self.transaction_id=(id)
17+
store[:transaction_id] = id
18+
end
19+
end
20+
end

0 commit comments

Comments
 (0)