paper_trail 6.0.1 → 6.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/CONTRIBUTING.md +45 -9
- data/.rubocop_todo.yml +2 -2
- data/CHANGELOG.md +22 -0
- data/README.md +1 -1
- data/lib/paper_trail/model_config.rb +6 -16
- data/lib/paper_trail/queries/versions/where_object.rb +60 -0
- data/lib/paper_trail/queries/versions/where_object_changes.rb +68 -0
- data/lib/paper_trail/record_trail.rb +71 -45
- data/lib/paper_trail/reifier.rb +243 -164
- data/lib/paper_trail/version_concern.rb +48 -48
- data/lib/paper_trail/version_number.rb +1 -1
- data/paper_trail.gemspec +23 -3
- data/spec/controllers/articles_controller_spec.rb +28 -0
- data/test/dummy/config/boot.rb +20 -6
- metadata +16 -11
- data/test/functional/enabled_for_controller_test.rb +0 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c23b36829183d413cfe6fa50f86b50dc5d5dd99a
|
4
|
+
data.tar.gz: c1964749e5fb1f1d23d8d066558d8d61323a6b73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31692c33ac64c0322c894038b1a75c50ba5231a42ba7ebfa08a08517b721d0a08eba2e2e821566586da4a7bca7c7da92b7f74aee257bc5c698dbe8e8284a42dd
|
7
|
+
data.tar.gz: 0fe50a103b744687e0e2acd02dbb24c5f32f82c0255a356e89f2a66a1c5bd4bd0b688ac7eb8394cb34fb08b856780cc8e55b53be6afbaea7f6f99c24cfc5d408
|
data/.github/CONTRIBUTING.md
CHANGED
@@ -18,7 +18,9 @@ Please use our [bug report template][1].
|
|
18
18
|
|
19
19
|
## Development
|
20
20
|
|
21
|
-
Install gems with `bundle exec appraisal install`.
|
21
|
+
Install gems with `bundle exec appraisal install`. This requires ruby >= 2.0.
|
22
|
+
(It is still possible to run the `ar-4.2` gemfile locally on ruby 1.9.3, but
|
23
|
+
not the `ar-5.0` gemfile.)
|
22
24
|
|
23
25
|
Testing is a little awkward because the test suite:
|
24
26
|
|
@@ -26,43 +28,73 @@ Testing is a little awkward because the test suite:
|
|
26
28
|
1. Contains a "dummy" rails app with three databases (test, foo, and bar)
|
27
29
|
1. Supports three different RDBMS': sqlite, mysql, and postgres
|
28
30
|
|
29
|
-
###
|
31
|
+
### Test sqlite, AR 4.2
|
30
32
|
|
31
33
|
```
|
32
34
|
# Create the appropriate database config. file
|
33
35
|
rm test/dummy/config/database.yml
|
34
36
|
DB=sqlite bundle exec rake prepare
|
35
37
|
|
36
|
-
# If this is the first test run ever, create databases
|
38
|
+
# If this is the first test run ever, create databases.
|
39
|
+
# We can't use `appraisal` inside the test dummy, so we must set `BUNDLE_GEMFILE`.
|
40
|
+
# See test/dummy/config/boot.rb for a complete explanation.
|
37
41
|
cd test/dummy
|
42
|
+
export BUNDLE_GEMFILE=../../gemfiles/ar_4.2.gemfile
|
38
43
|
RAILS_ENV=test bundle exec rake db:setup
|
39
44
|
RAILS_ENV=foo bundle exec rake db:setup
|
40
45
|
RAILS_ENV=bar bundle exec rake db:setup
|
46
|
+
unset BUNDLE_GEMFILE
|
47
|
+
cd ../..
|
48
|
+
|
49
|
+
# Run tests
|
50
|
+
DB=sqlite bundle exec appraisal ar-4.2 rake
|
51
|
+
```
|
52
|
+
|
53
|
+
### Test sqlite, AR 5
|
54
|
+
|
55
|
+
```
|
56
|
+
# Create the appropriate database config. file
|
57
|
+
rm test/dummy/config/database.yml
|
58
|
+
DB=sqlite bundle exec rake prepare
|
59
|
+
|
60
|
+
# If this is the first test run ever, create databases.
|
61
|
+
# We can't use `appraisal` inside the test dummy, so we must set `BUNDLE_GEMFILE`.
|
62
|
+
# See test/dummy/config/boot.rb for a complete explanation.
|
63
|
+
cd test/dummy
|
64
|
+
export BUNDLE_GEMFILE=../../gemfiles/ar_5.0.gemfile
|
65
|
+
RAILS_ENV=test bundle exec rake db:environment:set db:setup
|
66
|
+
RAILS_ENV=foo bundle exec rake db:environment:set db:setup
|
67
|
+
RAILS_ENV=bar bundle exec rake db:environment:set db:setup
|
68
|
+
unset BUNDLE_GEMFILE
|
41
69
|
cd ../..
|
42
70
|
|
43
71
|
# Run tests
|
44
72
|
DB=sqlite bundle exec appraisal ar-5.0 rake
|
45
73
|
```
|
46
74
|
|
47
|
-
###
|
75
|
+
### Test mysql, AR 5
|
48
76
|
|
49
77
|
```
|
50
78
|
# Create the appropriate database config. file
|
51
79
|
rm test/dummy/config/database.yml
|
52
80
|
DB=mysql bundle exec rake prepare
|
53
81
|
|
54
|
-
# If this is the first test run ever, create databases
|
82
|
+
# If this is the first test run ever, create databases.
|
83
|
+
# We can't use `appraisal` inside the test dummy, so we must set `BUNDLE_GEMFILE`.
|
84
|
+
# See test/dummy/config/boot.rb for a complete explanation.
|
55
85
|
cd test/dummy
|
56
|
-
|
57
|
-
RAILS_ENV=
|
58
|
-
RAILS_ENV=
|
86
|
+
export BUNDLE_GEMFILE=../../gemfiles/ar_5.0.gemfile
|
87
|
+
RAILS_ENV=test bundle exec rake db:environment:set db:setup
|
88
|
+
RAILS_ENV=foo bundle exec rake db:environment:set db:setup
|
89
|
+
RAILS_ENV=bar bundle exec rake db:environment:set db:setup
|
90
|
+
unset BUNDLE_GEMFILE
|
59
91
|
cd ../..
|
60
92
|
|
61
93
|
# Run tests
|
62
94
|
DB=mysql bundle exec appraisal ar-5.0 rake
|
63
95
|
```
|
64
96
|
|
65
|
-
###
|
97
|
+
### Test postgres, AR 5
|
66
98
|
|
67
99
|
```
|
68
100
|
# Create the appropriate database config. file
|
@@ -71,10 +103,14 @@ DB=postgres bundle exec rake prepare
|
|
71
103
|
|
72
104
|
# If this is the first test run ever, create databases.
|
73
105
|
# Unlike mysql, use create/migrate instead of setup.
|
106
|
+
# We can't use `appraisal` inside the test dummy, so we must set `BUNDLE_GEMFILE`.
|
107
|
+
# See test/dummy/config/boot.rb for a complete explanation.
|
74
108
|
cd test/dummy
|
109
|
+
export BUNDLE_GEMFILE=../../gemfiles/ar_5.0.gemfile
|
75
110
|
DB=postgres RAILS_ENV=test bundle exec rake db:drop db:create db:migrate
|
76
111
|
DB=postgres RAILS_ENV=foo bundle exec rake db:drop db:create db:migrate
|
77
112
|
DB=postgres RAILS_ENV=bar bundle exec rake db:drop db:create db:migrate
|
113
|
+
unset BUNDLE_GEMFILE
|
78
114
|
cd ../..
|
79
115
|
|
80
116
|
# Run tests
|
data/.rubocop_todo.yml
CHANGED
@@ -2,13 +2,13 @@
|
|
2
2
|
# one by one as the offenses are removed from the code base.
|
3
3
|
|
4
4
|
Metrics/AbcSize:
|
5
|
-
Max:
|
5
|
+
Max: 22 # Goal: 15
|
6
6
|
|
7
7
|
Metrics/CyclomaticComplexity:
|
8
8
|
Max: 8 # Goal: 6
|
9
9
|
|
10
10
|
Metrics/PerceivedComplexity:
|
11
|
-
Max:
|
11
|
+
Max: 9 # Goal: 7
|
12
12
|
|
13
13
|
Style/FrozenStringLiteralComment:
|
14
14
|
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -17,6 +17,28 @@ recommendations of [keepachangelog.com](http://keepachangelog.com/).
|
|
17
17
|
|
18
18
|
- None
|
19
19
|
|
20
|
+
## 6.0.2 (2016-12-13)
|
21
|
+
|
22
|
+
### Breaking Changes
|
23
|
+
|
24
|
+
- None
|
25
|
+
|
26
|
+
### Added
|
27
|
+
|
28
|
+
- None
|
29
|
+
|
30
|
+
### Fixed
|
31
|
+
|
32
|
+
- `88e513f` - Surprise argument modification bug in `where_object_changes`
|
33
|
+
- `c7efd62` - Column type-detection bug in `where_object_changes`
|
34
|
+
- [#905](https://github.com/airblade/paper_trail/pull/905) - Only invoke
|
35
|
+
`logger.warn` if `logger` instance exists
|
36
|
+
|
37
|
+
### Code Quality
|
38
|
+
|
39
|
+
- Improve Metrics/AbcSize from 30 to 22
|
40
|
+
- Improve Metrics/PerceivedComplexity from 10 to 9
|
41
|
+
|
20
42
|
## 6.0.1 (2016-12-04)
|
21
43
|
|
22
44
|
### Breaking Changes
|
data/README.md
CHANGED
@@ -11,7 +11,7 @@ has been destroyed.
|
|
11
11
|
| Version | Documentation |
|
12
12
|
| -------------- | ------------- |
|
13
13
|
| Unreleased | https://github.com/airblade/paper_trail/blob/master/README.md |
|
14
|
-
| 6.0.
|
14
|
+
| 6.0.2 | https://github.com/airblade/paper_trail/blob/v6.0.2/README.md |
|
15
15
|
| 5.2.3 | https://github.com/airblade/paper_trail/blob/v5.2.3/README.md |
|
16
16
|
| 4.2.0 | https://github.com/airblade/paper_trail/blob/v4.2.0/README.md |
|
17
17
|
| 3.0.9 | https://github.com/airblade/paper_trail/blob/v3.0.9/README.md |
|
@@ -124,22 +124,12 @@ module PaperTrail
|
|
124
124
|
|
125
125
|
@model_class.send :attr_accessor, :paper_trail_event
|
126
126
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
as: :item
|
134
|
-
)
|
135
|
-
else
|
136
|
-
@model_class.has_many(
|
137
|
-
@model_class.versions_association_name,
|
138
|
-
class_name: @model_class.version_class_name,
|
139
|
-
as: :item,
|
140
|
-
order: @model_class.paper_trail.version_class.timestamp_sort_order
|
141
|
-
)
|
142
|
-
end
|
127
|
+
@model_class.has_many(
|
128
|
+
@model_class.versions_association_name,
|
129
|
+
-> { order(model.timestamp_sort_order) },
|
130
|
+
class_name: @model_class.version_class_name,
|
131
|
+
as: :item
|
132
|
+
)
|
143
133
|
end
|
144
134
|
|
145
135
|
# Adds callbacks to record changes to habtm associations such that on save
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module PaperTrail
|
2
|
+
module Queries
|
3
|
+
module Versions
|
4
|
+
# For public API documentation, see `where_object` in
|
5
|
+
# `paper_trail/version_concern.rb`.
|
6
|
+
# @api private
|
7
|
+
class WhereObject
|
8
|
+
# - version_model_class - The class that VersionConcern was mixed into.
|
9
|
+
# - attributes - A `Hash` of attributes and values. See the public API
|
10
|
+
# documentation for details.
|
11
|
+
# @api private
|
12
|
+
def initialize(version_model_class, attributes)
|
13
|
+
@version_model_class = version_model_class
|
14
|
+
@attributes = attributes
|
15
|
+
end
|
16
|
+
|
17
|
+
# @api private
|
18
|
+
def execute
|
19
|
+
case @version_model_class.columns_hash["object"].type
|
20
|
+
when :jsonb
|
21
|
+
jsonb
|
22
|
+
when :json
|
23
|
+
json
|
24
|
+
else
|
25
|
+
text
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
# @api private
|
32
|
+
def json
|
33
|
+
predicates = []
|
34
|
+
values = []
|
35
|
+
@attributes.each do |field, value|
|
36
|
+
predicates.push "object->>? = ?"
|
37
|
+
values.concat([field, value.to_s])
|
38
|
+
end
|
39
|
+
sql = predicates.join(" and ")
|
40
|
+
@version_model_class.where(sql, *values)
|
41
|
+
end
|
42
|
+
|
43
|
+
# @api private
|
44
|
+
def jsonb
|
45
|
+
@version_model_class.where("object @> ?", @attributes.to_json)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @api private
|
49
|
+
def text
|
50
|
+
arel_field = @version_model_class.arel_table[:object]
|
51
|
+
where_conditions = @attributes.map { |field, value|
|
52
|
+
::PaperTrail.serializer.where_object_condition(arel_field, field, value)
|
53
|
+
}
|
54
|
+
where_conditions = where_conditions.reduce { |a, e| a.and(e) }
|
55
|
+
@version_model_class.where(where_conditions)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module PaperTrail
|
2
|
+
module Queries
|
3
|
+
module Versions
|
4
|
+
# For public API documentation, see `where_object` in
|
5
|
+
# `paper_trail/version_concern.rb`.
|
6
|
+
# @api private
|
7
|
+
class WhereObjectChanges
|
8
|
+
# - version_model_class - The class that VersionConcern was mixed into.
|
9
|
+
# - attributes - A `Hash` of attributes and values. See the public API
|
10
|
+
# documentation for details.
|
11
|
+
# @api private
|
12
|
+
def initialize(version_model_class, attributes)
|
13
|
+
@version_model_class = version_model_class
|
14
|
+
|
15
|
+
# Currently, this `deep_dup` is necessary because the `jsonb` branch
|
16
|
+
# modifies `@attributes`, and that would be a nasty suprise for
|
17
|
+
# consumers of this class.
|
18
|
+
# TODO: Stop modifying `@attributes`, then remove `deep_dup`.
|
19
|
+
@attributes = attributes.deep_dup
|
20
|
+
end
|
21
|
+
|
22
|
+
# @api private
|
23
|
+
def execute
|
24
|
+
case @version_model_class.columns_hash["object_changes"].type
|
25
|
+
when :jsonb
|
26
|
+
jsonb
|
27
|
+
when :json
|
28
|
+
json
|
29
|
+
else
|
30
|
+
text
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
def json
|
38
|
+
predicates = []
|
39
|
+
values = []
|
40
|
+
@attributes.each do |field, value|
|
41
|
+
predicates.push(
|
42
|
+
"((object_changes->>? ILIKE ?) OR (object_changes->>? ILIKE ?))"
|
43
|
+
)
|
44
|
+
values.concat([field, "[#{value.to_json},%", field, "[%,#{value.to_json}]%"])
|
45
|
+
end
|
46
|
+
sql = predicates.join(" and ")
|
47
|
+
@version_model_class.where(sql, *values)
|
48
|
+
end
|
49
|
+
|
50
|
+
# @api private
|
51
|
+
def jsonb
|
52
|
+
@attributes.each { |field, value| @attributes[field] = [value] }
|
53
|
+
@version_model_class.where("object_changes @> ?", @attributes.to_json)
|
54
|
+
end
|
55
|
+
|
56
|
+
# @api private
|
57
|
+
def text
|
58
|
+
arel_field = @version_model_class.arel_table[:object_changes]
|
59
|
+
where_conditions = @attributes.map { |field, value|
|
60
|
+
::PaperTrail.serializer.where_object_changes_condition(arel_field, field, value)
|
61
|
+
}
|
62
|
+
where_conditions = where_conditions.reduce { |a, e| a.and(e) }
|
63
|
+
@version_model_class.where(where_conditions)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -118,30 +118,47 @@ module PaperTrail
|
|
118
118
|
source_version.nil?
|
119
119
|
end
|
120
120
|
|
121
|
+
# Updates `data` from the model's `meta` option and from `controller_info`.
|
121
122
|
# @api private
|
122
|
-
def
|
123
|
-
|
123
|
+
def merge_metadata_into(data)
|
124
|
+
merge_metadata_from_model_into(data)
|
125
|
+
merge_metadata_from_controller_into(data)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Updates `data` from `controller_info`.
|
129
|
+
# @api private
|
130
|
+
def merge_metadata_from_controller_into(data)
|
131
|
+
data.merge(PaperTrail.controller_info || {})
|
132
|
+
end
|
133
|
+
|
134
|
+
# Updates `data` from the model's `meta` option.
|
135
|
+
# @api private
|
136
|
+
def merge_metadata_from_model_into(data)
|
124
137
|
@record.paper_trail_options[:meta].each do |k, v|
|
125
|
-
data[k] =
|
126
|
-
if v.respond_to?(:call)
|
127
|
-
v.call(@record)
|
128
|
-
elsif v.is_a?(Symbol) && @record.respond_to?(v, true)
|
129
|
-
# If it is an attribute that is changing in an existing object,
|
130
|
-
# be sure to grab the current version.
|
131
|
-
if @record.has_attribute?(v) &&
|
132
|
-
attribute_changed_in_latest_version?(v) &&
|
133
|
-
data[:event] != "create"
|
134
|
-
attribute_in_previous_version(v)
|
135
|
-
else
|
136
|
-
@record.send(v)
|
137
|
-
end
|
138
|
-
else
|
139
|
-
v
|
140
|
-
end
|
138
|
+
data[k] = model_metadatum(v, data[:event])
|
141
139
|
end
|
140
|
+
end
|
142
141
|
|
143
|
-
|
144
|
-
|
142
|
+
# Given a `value` from the model's `meta` option, returns an object to be
|
143
|
+
# persisted. The `value` can be a simple scalar value, but it can also
|
144
|
+
# be a symbol that names a model method, or even a Proc.
|
145
|
+
# @api private
|
146
|
+
def model_metadatum(value, event)
|
147
|
+
if value.respond_to?(:call)
|
148
|
+
value.call(@record)
|
149
|
+
elsif value.is_a?(Symbol) && @record.respond_to?(value, true)
|
150
|
+
# If it is an attribute that is changing in an existing object,
|
151
|
+
# be sure to grab the current version.
|
152
|
+
if event != "create" &&
|
153
|
+
@record.has_attribute?(value) &&
|
154
|
+
attribute_changed_in_latest_version?(value)
|
155
|
+
attribute_in_previous_version(value)
|
156
|
+
else
|
157
|
+
@record.send(value)
|
158
|
+
end
|
159
|
+
else
|
160
|
+
value
|
161
|
+
end
|
145
162
|
end
|
146
163
|
|
147
164
|
# Returns the object (not a Version) as it became next.
|
@@ -210,7 +227,7 @@ module PaperTrail
|
|
210
227
|
data[:object_changes] = recordable_object_changes
|
211
228
|
end
|
212
229
|
add_transaction_id_to(data)
|
213
|
-
|
230
|
+
merge_metadata_into(data)
|
214
231
|
end
|
215
232
|
|
216
233
|
def record_destroy
|
@@ -238,7 +255,7 @@ module PaperTrail
|
|
238
255
|
whodunnit: PaperTrail.whodunnit
|
239
256
|
}
|
240
257
|
add_transaction_id_to(data)
|
241
|
-
|
258
|
+
merge_metadata_into(data)
|
242
259
|
end
|
243
260
|
|
244
261
|
# Returns a boolean indicating whether to store serialized version diffs
|
@@ -280,7 +297,7 @@ module PaperTrail
|
|
280
297
|
data[:object_changes] = recordable_object_changes
|
281
298
|
end
|
282
299
|
add_transaction_id_to(data)
|
283
|
-
|
300
|
+
merge_metadata_into(data)
|
284
301
|
end
|
285
302
|
|
286
303
|
# Returns an object which can be assigned to the `object` attribute of a
|
@@ -329,29 +346,15 @@ module PaperTrail
|
|
329
346
|
# Saves associations if the join table for `VersionAssociation` exists.
|
330
347
|
def save_associations(version)
|
331
348
|
return unless PaperTrail.config.track_associations?
|
332
|
-
|
333
|
-
|
349
|
+
save_bt_associations(version)
|
350
|
+
save_habtm_associations(version)
|
334
351
|
end
|
335
352
|
|
336
|
-
|
353
|
+
# Save all `belongs_to` associations.
|
354
|
+
# @api private
|
355
|
+
def save_bt_associations(version)
|
337
356
|
@record.class.reflect_on_all_associations(:belongs_to).each do |assoc|
|
338
|
-
|
339
|
-
version_id: version.id,
|
340
|
-
foreign_key_name: assoc.foreign_key
|
341
|
-
}
|
342
|
-
|
343
|
-
if assoc.options[:polymorphic]
|
344
|
-
associated_record = @record.send(assoc.name) if @record.send(assoc.foreign_type)
|
345
|
-
if associated_record && associated_record.class.paper_trail.enabled?
|
346
|
-
assoc_version_args[:foreign_key_id] = associated_record.id
|
347
|
-
end
|
348
|
-
elsif assoc.klass.paper_trail.enabled?
|
349
|
-
assoc_version_args[:foreign_key_id] = @record.send(assoc.foreign_key)
|
350
|
-
end
|
351
|
-
|
352
|
-
if assoc_version_args.key?(:foreign_key_id)
|
353
|
-
PaperTrail::VersionAssociation.create(assoc_version_args)
|
354
|
-
end
|
357
|
+
save_bt_association(assoc, version)
|
355
358
|
end
|
356
359
|
end
|
357
360
|
|
@@ -359,7 +362,8 @@ module PaperTrail
|
|
359
362
|
# HABTM associations looked like before any changes were made, by using
|
360
363
|
# the `paper_trail_habtm` data structure. Then, we create
|
361
364
|
# `VersionAssociation` records for each of the associated records.
|
362
|
-
|
365
|
+
# @api private
|
366
|
+
def save_habtm_associations(version)
|
363
367
|
@record.class.reflect_on_all_associations(:has_and_belongs_to_many).each do |a|
|
364
368
|
next unless save_habtm_association?(a)
|
365
369
|
habtm_assoc_ids(a).each do |id|
|
@@ -502,12 +506,34 @@ module PaperTrail
|
|
502
506
|
end
|
503
507
|
|
504
508
|
def log_version_errors(version, action)
|
505
|
-
version.logger.warn(
|
509
|
+
version.logger && version.logger.warn(
|
506
510
|
"Unable to create version for #{action} of #{@record.class.name}" +
|
507
511
|
"##{@record.id}: " + version.errors.full_messages.join(", ")
|
508
512
|
)
|
509
513
|
end
|
510
514
|
|
515
|
+
# Save a single `belongs_to` association.
|
516
|
+
# @api private
|
517
|
+
def save_bt_association(assoc, version)
|
518
|
+
assoc_version_args = {
|
519
|
+
version_id: version.id,
|
520
|
+
foreign_key_name: assoc.foreign_key
|
521
|
+
}
|
522
|
+
|
523
|
+
if assoc.options[:polymorphic]
|
524
|
+
associated_record = @record.send(assoc.name) if @record.send(assoc.foreign_type)
|
525
|
+
if associated_record && associated_record.class.paper_trail.enabled?
|
526
|
+
assoc_version_args[:foreign_key_id] = associated_record.id
|
527
|
+
end
|
528
|
+
elsif assoc.klass.paper_trail.enabled?
|
529
|
+
assoc_version_args[:foreign_key_id] = @record.send(assoc.foreign_key)
|
530
|
+
end
|
531
|
+
|
532
|
+
if assoc_version_args.key?(:foreign_key_id)
|
533
|
+
PaperTrail::VersionAssociation.create(assoc_version_args)
|
534
|
+
end
|
535
|
+
end
|
536
|
+
|
511
537
|
# Returns true if the given HABTM association should be saved.
|
512
538
|
# @api private
|
513
539
|
def save_habtm_association?(assoc)
|