paper_trail 4.0.0 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +22 -7
- data/CONTRIBUTING.md +11 -0
- data/README.md +260 -229
- data/lib/paper_trail.rb +17 -13
- data/lib/paper_trail/cleaner.rb +21 -11
- data/lib/paper_trail/config.rb +3 -1
- data/lib/paper_trail/frameworks/active_record.rb +2 -2
- data/lib/paper_trail/frameworks/rails/controller.rb +11 -9
- data/lib/paper_trail/frameworks/sinatra.rb +2 -1
- data/lib/paper_trail/has_paper_trail.rb +90 -54
- data/lib/paper_trail/version_concern.rb +87 -58
- data/lib/paper_trail/version_number.rb +1 -1
- data/spec/models/skipper_spec.rb +38 -9
- data/spec/models/widget_spec.rb +2 -2
- data/test/dummy/db/migrate/20110208155312_set_up_test_tables.rb +2 -1
- data/test/dummy/db/schema.rb +63 -25
- data/test/unit/model_test.rb +2 -2
- metadata +47 -46
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 047fe27b3f2154c19030502f4d129dcdd2873146
|
4
|
+
data.tar.gz: 6b6f268b260b459e0e6df8340ec9d33cb5c07824
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 49c10975deb4b0f20617b4b770a1f6b99d2980df4072dd71da1dc48c7da85e409c6eeadcbfcc74f86f239b320e7ae73f6d7d2f72971439a39330d6f353b9f33e
|
7
|
+
data.tar.gz: 3ecddc1755c7d139e04716582bbe136163605eb33354acaf7e520bc0178dfe7c9d184c8f673f4bb744440c4e7113a58017c6de4fca9262ff99575bee764d804d
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
## 4.0.1
|
2
|
+
|
3
|
+
### Breaking Changes
|
4
|
+
|
5
|
+
- None
|
6
|
+
|
7
|
+
### Added
|
8
|
+
|
9
|
+
- None
|
10
|
+
|
11
|
+
### Fixed
|
12
|
+
|
13
|
+
- [#636](https://github.com/airblade/paper_trail/issues/636) -
|
14
|
+
Should compile assets without a db connection
|
15
|
+
- [#589](https://github.com/airblade/paper_trail/pull/589) /
|
16
|
+
[#588](https://github.com/airblade/paper_trail/issues/588) -
|
17
|
+
Fixes timestamp for "create" versions
|
18
|
+
|
1
19
|
## 4.0.0
|
2
20
|
|
3
21
|
This major release adds JSON column support in PostgreSQL, limited support for
|
@@ -5,7 +23,7 @@ versioning associations, various new configuration options, and a year's worth
|
|
5
23
|
of bug fixes. Thanks to everyone who helped test the two betas and two release
|
6
24
|
candidates.
|
7
25
|
|
8
|
-
###
|
26
|
+
### Breaking Changes
|
9
27
|
|
10
28
|
- Using a Rails initializer to reopen PaperTrail::Version or otherwise extend
|
11
29
|
PaperTrail is no longer recommended. An alternative is described in the
|
@@ -13,6 +31,9 @@ candidates.
|
|
13
31
|
https://github.com/airblade/paper_trail/pull/492.
|
14
32
|
- If you depend on the `RSpec` or `Cucumber` helpers, you must
|
15
33
|
[require them in your test helper](https://github.com/airblade/paper_trail#testing).
|
34
|
+
- [#566](https://github.com/airblade/paper_trail/pull/566) - Removed deprecated
|
35
|
+
methods `paper_trail_on` and `paper_trail_off`. Use `paper_trail_on!` and
|
36
|
+
`paper_trail_off!` instead.
|
16
37
|
- [#458](https://github.com/airblade/paper_trail/pull/458) - Version metadata
|
17
38
|
(the `:meta` option) from AR attributes for `create` events will now save the
|
18
39
|
current value instead of `nil`.
|
@@ -29,12 +50,6 @@ candidates.
|
|
29
50
|
- `3da1f104` - `PaperTrail.config` and `PaperTrail.configure` are now
|
30
51
|
identical: both return the `PaperTrail::Config` instance and also
|
31
52
|
yield it if a block is provided.
|
32
|
-
|
33
|
-
### Removed
|
34
|
-
|
35
|
-
- [#566](https://github.com/airblade/paper_trail/pull/566) - Removed deprecated
|
36
|
-
methods `paper_trail_on` and `paper_trail_off`. Use `paper_trail_on!` and
|
37
|
-
`paper_trail_off!` instead.
|
38
53
|
|
39
54
|
### Added
|
40
55
|
|
data/CONTRIBUTING.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
# Contributing
|
2
|
+
|
3
|
+
Thanks for your interest in PaperTrail! We appreciate bug reports, feature
|
4
|
+
suggestions, and especially pull requests.
|
5
|
+
|
6
|
+
Please do not use github issues to ask usage questions. We simply don't have
|
7
|
+
time to answer them all. Instead, please ask usage questions on Stack Overflow.
|
8
|
+
|
9
|
+
http://stackoverflow.com/tags/papertrail
|
10
|
+
|
11
|
+
Thanks, and happy versioning :)
|
data/README.md
CHANGED
@@ -1,72 +1,76 @@
|
|
1
|
-
# PaperTrail
|
1
|
+
# PaperTrail
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
[![Build Status][4]][5] [![Dependency Status][6]][7]
|
4
|
+
|
5
|
+
Track changes to your models, for auditing or versioning. See how a model looked
|
6
|
+
at any stage in its lifecycle, revert it to any version, or restore it after it
|
7
|
+
has been destroyed.
|
6
8
|
|
7
9
|
- [Features](#features)
|
8
10
|
- [Compatibility](#compatibility)
|
9
11
|
- [Installation](#installation)
|
10
12
|
- [API Summary](#api-summary)
|
11
13
|
- [Basic Usage](#basic-usage)
|
12
|
-
-
|
13
|
-
- [Choosing
|
14
|
-
- [Choosing
|
15
|
-
- [
|
16
|
-
- [
|
14
|
+
- Limiting What is Versioned, and When
|
15
|
+
- [Choosing Lifecycle Events To Monitor](#choosing-lifecycle-events-to-monitor)
|
16
|
+
- [Choosing When To Save New Versions](#choosing-when-to-save-new-versions)
|
17
|
+
- [Choosing Attributes To Monitor](#choosing-attributes-to-monitor)
|
18
|
+
- [Turning PaperTrail Off/On](#turning-papertrail-offon)
|
19
|
+
- [Limiting the Number of Versions Created](#limiting-the-number-of-versions-created)
|
20
|
+
- Working With Versions
|
21
|
+
- [Reverting And Undeleting A Model](#reverting-and-undeleting-a-model)
|
22
|
+
- [Navigating Versions](#navigating-versions)
|
23
|
+
- [Diffing Versions](#diffing-versions)
|
24
|
+
- [Deleting Old Versions](#deleting-old-versions)
|
17
25
|
- [Finding Out Who Was Responsible For A Change](#finding-out-who-was-responsible-for-a-change)
|
18
26
|
- [Custom Version Classes](#custom-version-classes)
|
19
27
|
- [Associations](#associations)
|
20
28
|
- [Storing metadata](#storing-metadata)
|
21
|
-
- [Diffing Versions](#diffing-versions)
|
22
|
-
- [Turning PaperTrail Off/On](#turning-papertrail-offon)
|
23
29
|
- [Using a custom serializer](#using-a-custom-serializer)
|
24
30
|
- [SerializedAttributes support](#serializedattributes-support)
|
25
|
-
- [Limiting the Number of Versions Created](#limiting-the-number-of-versions-created)
|
26
|
-
- [Deleting Old Versions](#deleting-old-versions)
|
27
31
|
- [Testing](#testing)
|
28
32
|
|
29
33
|
## Features
|
30
34
|
|
31
|
-
* Stores
|
32
|
-
* Does not store updates which don't change anything
|
33
|
-
*
|
34
|
-
*
|
35
|
-
*
|
36
|
-
*
|
37
|
-
*
|
38
|
-
*
|
39
|
-
*
|
40
|
-
*
|
41
|
-
*
|
42
|
-
*
|
43
|
-
*
|
44
|
-
*
|
45
|
-
*
|
46
|
-
*
|
47
|
-
*
|
48
|
-
*
|
49
|
-
*
|
50
|
-
*
|
51
|
-
|
35
|
+
* Stores create, update and destroy events
|
36
|
+
* Does not store updates which don't change anything
|
37
|
+
* Support for versioning associated records
|
38
|
+
* Can store metadata with each version record
|
39
|
+
* Who was responsible for a change
|
40
|
+
* Arbitrary model-level metadata (useful for filtering versions)
|
41
|
+
* Arbitrary controller-level information e.g. remote IP
|
42
|
+
* Configurable
|
43
|
+
* No configuration necessary, but if you want to ..
|
44
|
+
* Configure which events (create, update and destroy) are versioned
|
45
|
+
* Configure which attributes must change for an update to be versioned
|
46
|
+
* Turn off/on by model, request, or globally
|
47
|
+
* Use separate tables for separate models
|
48
|
+
* Extensible
|
49
|
+
* Write a custom version class for complete control
|
50
|
+
* Write custom version classes for each of your models
|
51
|
+
* Work with versions
|
52
|
+
* Restore any version, including the original, even once destroyed
|
53
|
+
* Restore any version even if the schema has since changed
|
54
|
+
* Restore the version as of a particular time
|
55
|
+
* Thoroughly tested
|
56
|
+
* Threadsafe
|
52
57
|
|
53
58
|
## Compatibility
|
54
59
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
The Rails 2.3 code is on the [`rails2`][11] branch and tagged `v1.x`. These branches are both stable with their respective versions of Rails but will not have new features added/backported to them.
|
60
|
+
| paper_trail | branch | tags | ruby | activerecord |
|
61
|
+
| ----------- | ---------- | ------ | -------- | ------------ |
|
62
|
+
| 4 | master | v4.x | >= 1.8.7 | >= 3.0, < 6 |
|
63
|
+
| 3 | 3.0-stable | v3.x | >= 1.8.7 | >= 3.0, < 5 |
|
64
|
+
| 2 | 2.7-stable | v2.x | >= 1.8.7 | >= 3.0, < 4 |
|
65
|
+
| 1 | rails2 | v1.x | >= 1.8.7 | >= 2.3, < 3 |
|
62
66
|
|
63
67
|
## Installation
|
64
68
|
|
65
|
-
### Rails 3
|
69
|
+
### Rails 3 and 4
|
66
70
|
|
67
71
|
1. Add PaperTrail to your `Gemfile`.
|
68
72
|
|
69
|
-
`gem 'paper_trail', '~> 4.0.
|
73
|
+
`gem 'paper_trail', '~> 4.0.1'`
|
70
74
|
|
71
75
|
2. Generate a migration which will add a `versions` table to your database.
|
72
76
|
|
@@ -89,7 +93,7 @@ setting up your app with PaperTrail will look something like this:
|
|
89
93
|
|
90
94
|
1. Add PaperTrail to your `Gemfile`.
|
91
95
|
|
92
|
-
`gem 'paper_trail', '~> 4.0.
|
96
|
+
`gem 'paper_trail', '~> 4.0.1'`
|
93
97
|
|
94
98
|
2. Generate a migration to add a `versions` table to your database.
|
95
99
|
|
@@ -435,6 +439,122 @@ class Article < ActiveRecord::Base
|
|
435
439
|
end
|
436
440
|
```
|
437
441
|
|
442
|
+
## Turning PaperTrail Off/On
|
443
|
+
|
444
|
+
Sometimes you don't want to store changes. Perhaps you are only interested in
|
445
|
+
changes made by your users and don't need to store changes you make yourself in,
|
446
|
+
say, a migration -- or when testing your application.
|
447
|
+
|
448
|
+
You can turn PaperTrail on or off in three ways: globally, per request, or per
|
449
|
+
class.
|
450
|
+
|
451
|
+
### Globally
|
452
|
+
|
453
|
+
On a global level you can turn PaperTrail off like this:
|
454
|
+
|
455
|
+
```ruby
|
456
|
+
PaperTrail.enabled = false
|
457
|
+
```
|
458
|
+
|
459
|
+
For example, you might want to disable PaperTrail in your Rails application's
|
460
|
+
test environment to speed up your tests. This will do it (note: this gets done
|
461
|
+
automatically for `RSpec` and `Cucumber`, please see the [Testing
|
462
|
+
section](#testing)):
|
463
|
+
|
464
|
+
```ruby
|
465
|
+
# in config/environments/test.rb
|
466
|
+
config.after_initialize do
|
467
|
+
PaperTrail.enabled = false
|
468
|
+
end
|
469
|
+
```
|
470
|
+
|
471
|
+
If you disable PaperTrail in your test environment but want to enable it for
|
472
|
+
specific tests, you can add a helper like this to your test helper:
|
473
|
+
|
474
|
+
```ruby
|
475
|
+
# in test/test_helper.rb
|
476
|
+
def with_versioning
|
477
|
+
was_enabled = PaperTrail.enabled?
|
478
|
+
was_enabled_for_controller = PaperTrail.enabled_for_controller?
|
479
|
+
PaperTrail.enabled = true
|
480
|
+
PaperTrail.enabled_for_controller = true
|
481
|
+
begin
|
482
|
+
yield
|
483
|
+
ensure
|
484
|
+
PaperTrail.enabled = was_enabled
|
485
|
+
PaperTrail.enabled_for_controller = was_enabled_for_controller
|
486
|
+
end
|
487
|
+
end
|
488
|
+
```
|
489
|
+
|
490
|
+
And then use it in your tests like this:
|
491
|
+
|
492
|
+
```ruby
|
493
|
+
test "something that needs versioning" do
|
494
|
+
with_versioning do
|
495
|
+
# your test
|
496
|
+
end
|
497
|
+
end
|
498
|
+
```
|
499
|
+
|
500
|
+
### Per request
|
501
|
+
|
502
|
+
You can turn PaperTrail on or off per request by adding a
|
503
|
+
`paper_trail_enabled_for_controller` method to your controller which returns
|
504
|
+
`true` or `false`:
|
505
|
+
|
506
|
+
```ruby
|
507
|
+
class ApplicationController < ActionController::Base
|
508
|
+
def paper_trail_enabled_for_controller
|
509
|
+
request.user_agent != 'Disable User-Agent'
|
510
|
+
end
|
511
|
+
end
|
512
|
+
```
|
513
|
+
|
514
|
+
### Per class
|
515
|
+
|
516
|
+
If you are about to change some widgets and you don't want a paper trail of your
|
517
|
+
changes, you can turn PaperTrail off like this:
|
518
|
+
|
519
|
+
```ruby
|
520
|
+
Widget.paper_trail_off!
|
521
|
+
```
|
522
|
+
|
523
|
+
And on again like this:
|
524
|
+
|
525
|
+
```ruby
|
526
|
+
Widget.paper_trail_on!
|
527
|
+
```
|
528
|
+
|
529
|
+
### Per method call
|
530
|
+
|
531
|
+
You can call a method without creating a new version using `without_versioning`.
|
532
|
+
It takes either a method name as a symbol:
|
533
|
+
|
534
|
+
```ruby
|
535
|
+
@widget.without_versioning :destroy
|
536
|
+
```
|
537
|
+
|
538
|
+
Or a block:
|
539
|
+
|
540
|
+
```ruby
|
541
|
+
@widget.without_versioning do
|
542
|
+
@widget.update_attributes :name => 'Ford'
|
543
|
+
end
|
544
|
+
```
|
545
|
+
|
546
|
+
## Limiting the Number of Versions Created
|
547
|
+
|
548
|
+
Configure `version_limit` to cap the number of versions saved per record. This
|
549
|
+
does not apply to `create` events.
|
550
|
+
|
551
|
+
```ruby
|
552
|
+
# Limit: 4 versions per record (3 most recent, plus a `create` event)
|
553
|
+
PaperTrail.config.version_limit = 3
|
554
|
+
# Remove the limit
|
555
|
+
PaperTrail.config.version_limit = nil
|
556
|
+
```
|
557
|
+
|
438
558
|
## Reverting And Undeleting A Model
|
439
559
|
|
440
560
|
PaperTrail makes reverting to a previous version easy:
|
@@ -528,6 +648,85 @@ And you can perform `WHERE` queries for object versions based on attributes:
|
|
528
648
|
PaperTrail::Version.where_object(content: "Hello", title: "Article")
|
529
649
|
```
|
530
650
|
|
651
|
+
## Diffing Versions
|
652
|
+
|
653
|
+
There are two scenarios: diffing adjacent versions and diffing non-adjacent
|
654
|
+
versions.
|
655
|
+
|
656
|
+
The best way to diff adjacent versions is to get PaperTrail to do it for you.
|
657
|
+
If you add an `object_changes` text column to your `versions` table, either at
|
658
|
+
installation time with the `rails generate paper_trail:install --with-changes`
|
659
|
+
option or manually, PaperTrail will store the `changes` diff (excluding any
|
660
|
+
attributes PaperTrail is ignoring) in each `update` version. You can use the
|
661
|
+
`version.changeset` method to retrieve it. For example:
|
662
|
+
|
663
|
+
```ruby
|
664
|
+
widget = Widget.create :name => 'Bob'
|
665
|
+
widget.versions.last.changeset
|
666
|
+
# {
|
667
|
+
# "name"=>[nil, "Bob"],
|
668
|
+
# "created_at"=>[nil, 2015-08-10 04:10:40 UTC],
|
669
|
+
# "updated_at"=>[nil, 2015-08-10 04:10:40 UTC],
|
670
|
+
# "id"=>[nil, 1]
|
671
|
+
# }
|
672
|
+
widget.update_attributes :name => 'Robert'
|
673
|
+
widget.versions.last.changeset
|
674
|
+
# {
|
675
|
+
# "name"=>["Bob", "Robert"],
|
676
|
+
# "updated_at"=>[2015-08-10 04:13:19 UTC, 2015-08-10 04:13:19 UTC]
|
677
|
+
# }
|
678
|
+
widget.destroy
|
679
|
+
widget.versions.last.changeset
|
680
|
+
# {}
|
681
|
+
```
|
682
|
+
|
683
|
+
The `object_changes` are only stored for creation and updates, not when an
|
684
|
+
object is destroyed.
|
685
|
+
|
686
|
+
Please be aware that PaperTrail doesn't use diffs internally. When I designed
|
687
|
+
PaperTrail I wanted simplicity and robustness so I decided to make each version
|
688
|
+
of an object self-contained. A version stores all of its object's data, not a
|
689
|
+
diff from the previous version. This means you can delete any version without
|
690
|
+
affecting any other.
|
691
|
+
|
692
|
+
To diff non-adjacent versions you'll have to write your own code. These
|
693
|
+
libraries may help:
|
694
|
+
|
695
|
+
For diffing two strings:
|
696
|
+
|
697
|
+
* [htmldiff][19]: expects but doesn't require HTML input and produces HTML
|
698
|
+
output. Works very well but slows down significantly on large (e.g. 5,000
|
699
|
+
word) inputs.
|
700
|
+
* [differ][20]: expects plain text input and produces plain
|
701
|
+
text/coloured/HTML/any output. Can do character-wise, word-wise, line-wise,
|
702
|
+
or arbitrary-boundary-string-wise diffs. Works very well on non-HTML input.
|
703
|
+
* [diff-lcs][21]: old-school, line-wise diffs.
|
704
|
+
|
705
|
+
For diffing two ActiveRecord objects:
|
706
|
+
|
707
|
+
* [Jeremy Weiskotten's PaperTrail fork][22]: uses ActiveSupport's diff to return
|
708
|
+
an array of hashes of the changes.
|
709
|
+
* [activerecord-diff][23]: rather like ActiveRecord::Dirty but also allows you
|
710
|
+
to specify which columns to compare.
|
711
|
+
|
712
|
+
If you wish to selectively record changes for some models but not others you
|
713
|
+
can opt out of recording changes by passing `:save_changes => false` to your
|
714
|
+
`has_paper_trail` method declaration.
|
715
|
+
|
716
|
+
## Deleting Old Versions
|
717
|
+
|
718
|
+
Over time your `versions` table will grow to an unwieldy size. Because each
|
719
|
+
version is self-contained (see the Diffing section above for more) you can
|
720
|
+
simply delete any records you don't want any more. For example:
|
721
|
+
|
722
|
+
```sql
|
723
|
+
sql> delete from versions where created_at < 2010-06-01;
|
724
|
+
```
|
725
|
+
|
726
|
+
```ruby
|
727
|
+
PaperTrail::Version.delete_all ["created_at < ?", 1.week.ago]
|
728
|
+
```
|
729
|
+
|
531
730
|
## Finding Out Who Was Responsible For A Change
|
532
731
|
|
533
732
|
If your `ApplicationController` has a `current_user` method, PaperTrail will
|
@@ -670,6 +869,11 @@ end
|
|
670
869
|
|
671
870
|
## Associations
|
672
871
|
|
872
|
+
**Experimental Feature: Known Issues:**
|
873
|
+
[#542](https://github.com/airblade/paper_trail/issues/542),
|
874
|
+
[#590](https://github.com/airblade/paper_trail/issues/590).
|
875
|
+
See also: Caveats below.
|
876
|
+
|
673
877
|
PaperTrail can restore three types of associations: Has-One, Has-Many, and
|
674
878
|
Has-Many-Through. In order to do this, you will need to create a
|
675
879
|
`version_associations` table, either at installation time with the `rails
|
@@ -884,7 +1088,7 @@ end
|
|
884
1088
|
|
885
1089
|
### Protected Attributes and Metadata
|
886
1090
|
|
887
|
-
If you are using rails 3 or the [protected_attributes][17] gem you must declare
|
1091
|
+
If you are using rails 3 or the [protected_attributes][17] gem you must declare
|
888
1092
|
your metadata columns to be `attr_accessible`.
|
889
1093
|
|
890
1094
|
```ruby
|
@@ -900,164 +1104,6 @@ end
|
|
900
1104
|
If you're using [strong_parameters][18] instead of [protected_attributes][17]
|
901
1105
|
then there is no need to use `attr_accessible`.
|
902
1106
|
|
903
|
-
## Diffing Versions
|
904
|
-
|
905
|
-
There are two scenarios: diffing adjacent versions and diffing non-adjacent
|
906
|
-
versions.
|
907
|
-
|
908
|
-
The best way to diff adjacent versions is to get PaperTrail to do it for you.
|
909
|
-
If you add an `object_changes` text column to your `versions` table, either at
|
910
|
-
installation time with the `rails generate paper_trail:install --with-changes`
|
911
|
-
option or manually, PaperTrail will store the `changes` diff (excluding any
|
912
|
-
attributes PaperTrail is ignoring) in each `update` version. You can use the
|
913
|
-
`version.changeset` method to retrieve it. For example:
|
914
|
-
|
915
|
-
```ruby
|
916
|
-
widget = Widget.create :name => 'Bob'
|
917
|
-
widget.versions.last.changeset # {'name' => [nil, 'Bob']}
|
918
|
-
widget.update_attributes :name => 'Robert'
|
919
|
-
widget.versions.last.changeset # {'name' => ['Bob', 'Robert']}
|
920
|
-
widget.destroy
|
921
|
-
widget.versions.last.changeset # {}
|
922
|
-
```
|
923
|
-
|
924
|
-
Note PaperTrail only stores the changes for creation and updates; it doesn't
|
925
|
-
store anything when an object is destroyed.
|
926
|
-
|
927
|
-
Please be aware that PaperTrail doesn't use diffs internally. When I designed
|
928
|
-
PaperTrail I wanted simplicity and robustness so I decided to make each version
|
929
|
-
of an object self-contained. A version stores all of its object's data, not a
|
930
|
-
diff from the previous version. This means you can delete any version without
|
931
|
-
affecting any other.
|
932
|
-
|
933
|
-
To diff non-adjacent versions you'll have to write your own code. These
|
934
|
-
libraries may help:
|
935
|
-
|
936
|
-
For diffing two strings:
|
937
|
-
|
938
|
-
* [htmldiff][19]: expects but doesn't require HTML input and produces HTML
|
939
|
-
output. Works very well but slows down significantly on large (e.g. 5,000
|
940
|
-
word) inputs.
|
941
|
-
* [differ][20]: expects plain text input and produces plain
|
942
|
-
text/coloured/HTML/any output. Can do character-wise, word-wise, line-wise,
|
943
|
-
or arbitrary-boundary-string-wise diffs. Works very well on non-HTML input.
|
944
|
-
* [diff-lcs][21]: old-school, line-wise diffs.
|
945
|
-
|
946
|
-
For diffing two ActiveRecord objects:
|
947
|
-
|
948
|
-
* [Jeremy Weiskotten's PaperTrail fork][22]: uses ActiveSupport's diff to return
|
949
|
-
an array of hashes of the changes.
|
950
|
-
* [activerecord-diff][23]: rather like ActiveRecord::Dirty but also allows you
|
951
|
-
to specify which columns to compare.
|
952
|
-
|
953
|
-
If you wish to selectively record changes for some models but not others you
|
954
|
-
can opt out of recording changes by passing `:save_changes => false` to your
|
955
|
-
`has_paper_trail` method declaration.
|
956
|
-
|
957
|
-
## Turning PaperTrail Off/On
|
958
|
-
|
959
|
-
Sometimes you don't want to store changes. Perhaps you are only interested in
|
960
|
-
changes made by your users and don't need to store changes you make yourself in,
|
961
|
-
say, a migration -- or when testing your application.
|
962
|
-
|
963
|
-
You can turn PaperTrail on or off in three ways: globally, per request, or per
|
964
|
-
class.
|
965
|
-
|
966
|
-
### Globally
|
967
|
-
|
968
|
-
On a global level you can turn PaperTrail off like this:
|
969
|
-
|
970
|
-
```ruby
|
971
|
-
PaperTrail.enabled = false
|
972
|
-
```
|
973
|
-
|
974
|
-
For example, you might want to disable PaperTrail in your Rails application's
|
975
|
-
test environment to speed up your tests. This will do it (note: this gets done
|
976
|
-
automatically for `RSpec` and `Cucumber`, please see the [Testing
|
977
|
-
section](#testing)):
|
978
|
-
|
979
|
-
```ruby
|
980
|
-
# in config/environments/test.rb
|
981
|
-
config.after_initialize do
|
982
|
-
PaperTrail.enabled = false
|
983
|
-
end
|
984
|
-
```
|
985
|
-
|
986
|
-
If you disable PaperTrail in your test environment but want to enable it for
|
987
|
-
specific tests, you can add a helper like this to your test helper:
|
988
|
-
|
989
|
-
```ruby
|
990
|
-
# in test/test_helper.rb
|
991
|
-
def with_versioning
|
992
|
-
was_enabled = PaperTrail.enabled?
|
993
|
-
was_enabled_for_controller = PaperTrail.enabled_for_controller?
|
994
|
-
PaperTrail.enabled = true
|
995
|
-
PaperTrail.enabled_for_controller = true
|
996
|
-
begin
|
997
|
-
yield
|
998
|
-
ensure
|
999
|
-
PaperTrail.enabled = was_enabled
|
1000
|
-
PaperTrail.enabled_for_controller = was_enabled_for_controller
|
1001
|
-
end
|
1002
|
-
end
|
1003
|
-
```
|
1004
|
-
|
1005
|
-
And then use it in your tests like this:
|
1006
|
-
|
1007
|
-
```ruby
|
1008
|
-
test "something that needs versioning" do
|
1009
|
-
with_versioning do
|
1010
|
-
# your test
|
1011
|
-
end
|
1012
|
-
end
|
1013
|
-
```
|
1014
|
-
|
1015
|
-
### Per request
|
1016
|
-
|
1017
|
-
You can turn PaperTrail on or off per request by adding a
|
1018
|
-
`paper_trail_enabled_for_controller` method to your controller which returns
|
1019
|
-
`true` or `false`:
|
1020
|
-
|
1021
|
-
```ruby
|
1022
|
-
class ApplicationController < ActionController::Base
|
1023
|
-
def paper_trail_enabled_for_controller
|
1024
|
-
request.user_agent != 'Disable User-Agent'
|
1025
|
-
end
|
1026
|
-
end
|
1027
|
-
```
|
1028
|
-
|
1029
|
-
### Per class
|
1030
|
-
|
1031
|
-
If you are about to change some widgets and you don't want a paper trail of your
|
1032
|
-
changes, you can turn PaperTrail off like this:
|
1033
|
-
|
1034
|
-
```ruby
|
1035
|
-
Widget.paper_trail_off!
|
1036
|
-
```
|
1037
|
-
|
1038
|
-
And on again like this:
|
1039
|
-
|
1040
|
-
```ruby
|
1041
|
-
Widget.paper_trail_on!
|
1042
|
-
```
|
1043
|
-
|
1044
|
-
### Per method call
|
1045
|
-
|
1046
|
-
You can call a method without creating a new version using `without_versioning`.
|
1047
|
-
It takes either a method name as a symbol:
|
1048
|
-
|
1049
|
-
```ruby
|
1050
|
-
@widget.without_versioning :destroy
|
1051
|
-
```
|
1052
|
-
|
1053
|
-
Or a block:
|
1054
|
-
|
1055
|
-
```ruby
|
1056
|
-
@widget.without_versioning do
|
1057
|
-
@widget.update_attributes :name => 'Ford'
|
1058
|
-
end
|
1059
|
-
```
|
1060
|
-
|
1061
1107
|
## Using a custom serializer
|
1062
1108
|
|
1063
1109
|
By default, PaperTrail stores your changes as a `YAML` dump. You can override
|
@@ -1091,6 +1137,17 @@ end
|
|
1091
1137
|
Note: You don't need to use a particular serializer for the PostgreSQL `JSON`
|
1092
1138
|
column type.
|
1093
1139
|
|
1140
|
+
#### Convert a column from text to json
|
1141
|
+
|
1142
|
+
Postgres' `alter column` command will not automatically convert a `text`
|
1143
|
+
column to `json`, but it can still be done with plain SQL.
|
1144
|
+
|
1145
|
+
```sql
|
1146
|
+
alter table versions
|
1147
|
+
alter column object type json
|
1148
|
+
using object::json;
|
1149
|
+
```
|
1150
|
+
|
1094
1151
|
## SerializedAttributes support
|
1095
1152
|
|
1096
1153
|
PaperTrail has a config option that can be used to enable/disable whether
|
@@ -1110,32 +1167,6 @@ PaperTrail.config.serialized_attributes = false
|
|
1110
1167
|
PaperTrail.serialized_attributes?
|
1111
1168
|
```
|
1112
1169
|
|
1113
|
-
## Limiting the Number of Versions Created
|
1114
|
-
|
1115
|
-
Configure `version_limit` to cap the number of versions saved per record. This
|
1116
|
-
does not apply to `create` events.
|
1117
|
-
|
1118
|
-
```ruby
|
1119
|
-
# Limit: 4 versions per record (3 most recent, plus a `create` event)
|
1120
|
-
PaperTrail.config.version_limit = 3
|
1121
|
-
# Remove the limit
|
1122
|
-
PaperTrail.config.version_limit = nil
|
1123
|
-
```
|
1124
|
-
|
1125
|
-
## Deleting Old Versions
|
1126
|
-
|
1127
|
-
Over time your `versions` table will grow to an unwieldy size. Because each
|
1128
|
-
version is self-contained (see the Diffing section above for more) you can
|
1129
|
-
simply delete any records you don't want any more. For example:
|
1130
|
-
|
1131
|
-
```sql
|
1132
|
-
sql> delete from versions where created_at < 2010-06-01;
|
1133
|
-
```
|
1134
|
-
|
1135
|
-
```ruby
|
1136
|
-
PaperTrail::Version.delete_all ["created_at < ?", 1.week.ago]
|
1137
|
-
```
|
1138
|
-
|
1139
1170
|
## Testing
|
1140
1171
|
|
1141
1172
|
You may want to turn PaperTrail off to speed up your tests. See the [Turning
|