vestal_versions 1.0.2 → 2.0.0
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.
- data/.gitignore +19 -20
 - data/.travis.yml +22 -0
 - data/CHANGELOG.md +7 -0
 - data/Gemfile +10 -0
 - data/README.rdoc +63 -36
 - data/Rakefile +4 -43
 - data/gemfiles/activerecord_3_0.gemfile +10 -0
 - data/gemfiles/activerecord_3_1.gemfile +10 -0
 - data/gemfiles/activerecord_3_2.gemfile +10 -0
 - data/gemfiles/activerecord_4_0.gemfile +10 -0
 - data/lib/generators/vestal_versions.rb +11 -0
 - data/lib/generators/vestal_versions/migration/migration_generator.rb +17 -0
 - data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/initializer.rb +0 -0
 - data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/migration.rb +4 -3
 - data/lib/vestal_versions.rb +39 -12
 - data/lib/vestal_versions/changes.rb +43 -47
 - data/lib/vestal_versions/conditions.rb +31 -43
 - data/lib/vestal_versions/control.rb +162 -138
 - data/lib/vestal_versions/creation.rb +67 -59
 - data/lib/vestal_versions/deletion.rb +37 -0
 - data/lib/vestal_versions/options.rb +6 -10
 - data/lib/vestal_versions/reload.rb +7 -14
 - data/lib/vestal_versions/reset.rb +15 -19
 - data/lib/vestal_versions/reversion.rb +64 -52
 - data/lib/vestal_versions/users.rb +36 -39
 - data/lib/vestal_versions/version.rb +57 -2
 - data/lib/vestal_versions/version_tagging.rb +51 -0
 - data/lib/vestal_versions/versioned.rb +14 -17
 - data/lib/vestal_versions/versions.rb +22 -7
 - data/spec/spec_helper.rb +28 -0
 - data/spec/support/models.rb +19 -0
 - data/spec/support/schema.rb +25 -0
 - data/spec/vestal_versions/changes_spec.rb +134 -0
 - data/spec/vestal_versions/conditions_spec.rb +103 -0
 - data/spec/vestal_versions/control_spec.rb +120 -0
 - data/spec/vestal_versions/creation_spec.rb +90 -0
 - data/spec/vestal_versions/deletion_spec.rb +86 -0
 - data/spec/vestal_versions/options_spec.rb +45 -0
 - data/spec/vestal_versions/reload_spec.rb +18 -0
 - data/spec/vestal_versions/reset_spec.rb +111 -0
 - data/spec/vestal_versions/reversion_spec.rb +103 -0
 - data/spec/vestal_versions/users_spec.rb +21 -0
 - data/spec/vestal_versions/version_spec.rb +61 -0
 - data/spec/vestal_versions/version_tagging_spec.rb +39 -0
 - data/spec/vestal_versions/versioned_spec.rb +16 -0
 - data/spec/vestal_versions/versions_spec.rb +176 -0
 - data/vestal_versions.gemspec +18 -100
 - metadata +153 -102
 - data/VERSION +0 -1
 - data/generators/vestal_versions/vestal_versions_generator.rb +0 -10
 - data/init.rb +0 -1
 - data/lib/vestal_versions/configuration.rb +0 -40
 - data/lib/vestal_versions/tagging.rb +0 -50
 - data/test/changes_test.rb +0 -169
 - data/test/conditions_test.rb +0 -137
 - data/test/configuration_test.rb +0 -39
 - data/test/control_test.rb +0 -152
 - data/test/creation_test.rb +0 -110
 - data/test/options_test.rb +0 -52
 - data/test/reload_test.rb +0 -19
 - data/test/reset_test.rb +0 -112
 - data/test/reversion_test.rb +0 -68
 - data/test/schema.rb +0 -43
 - data/test/tagging_test.rb +0 -39
 - data/test/test_helper.rb +0 -11
 - data/test/users_test.rb +0 -25
 - data/test/version_test.rb +0 -43
 - data/test/versioned_test.rb +0 -18
 - data/test/versions_test.rb +0 -172
 
    
        data/.gitignore
    CHANGED
    
    | 
         @@ -1,22 +1,21 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
             
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
            ## EMACS
         
     | 
| 
       9 
     | 
    
         
            -
            *~
         
     | 
| 
       10 
     | 
    
         
            -
            \#*
         
     | 
| 
       11 
     | 
    
         
            -
            .\#*
         
     | 
| 
       12 
     | 
    
         
            -
             
     | 
| 
       13 
     | 
    
         
            -
            ## VIM
         
     | 
| 
       14 
     | 
    
         
            -
            *.swp
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
            ## PROJECT::GENERAL
         
     | 
| 
      
 1 
     | 
    
         
            +
            *.gem
         
     | 
| 
      
 2 
     | 
    
         
            +
            *.rbc
         
     | 
| 
      
 3 
     | 
    
         
            +
            .bundle
         
     | 
| 
      
 4 
     | 
    
         
            +
            .config
         
     | 
| 
      
 5 
     | 
    
         
            +
            .rvmrc
         
     | 
| 
      
 6 
     | 
    
         
            +
            .yardoc
         
     | 
| 
       17 
7 
     | 
    
         
             
            coverage
         
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 8 
     | 
    
         
            +
            doc/
         
     | 
| 
      
 9 
     | 
    
         
            +
            Gemfile.lock
         
     | 
| 
      
 10 
     | 
    
         
            +
            gemfiles/*.lock
         
     | 
| 
      
 11 
     | 
    
         
            +
            InstalledFiles
         
     | 
| 
      
 12 
     | 
    
         
            +
            lib/bundler/man
         
     | 
| 
       19 
13 
     | 
    
         
             
            pkg
         
     | 
| 
       20 
     | 
    
         
            -
             
     | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
       22 
     | 
    
         
            -
             
     | 
| 
      
 14 
     | 
    
         
            +
            rdoc
         
     | 
| 
      
 15 
     | 
    
         
            +
            spec/reports
         
     | 
| 
      
 16 
     | 
    
         
            +
            test/tmp
         
     | 
| 
      
 17 
     | 
    
         
            +
            test/version_tmp
         
     | 
| 
      
 18 
     | 
    
         
            +
            tmp
         
     | 
| 
      
 19 
     | 
    
         
            +
            _yardoc
         
     | 
| 
      
 20 
     | 
    
         
            +
            .ruby-gemset
         
     | 
| 
      
 21 
     | 
    
         
            +
            .ruby-version
         
     | 
    
        data/.travis.yml
    ADDED
    
    | 
         @@ -0,0 +1,22 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            branches:
         
     | 
| 
      
 2 
     | 
    
         
            +
              only:
         
     | 
| 
      
 3 
     | 
    
         
            +
                - master
         
     | 
| 
      
 4 
     | 
    
         
            +
            gemfile:
         
     | 
| 
      
 5 
     | 
    
         
            +
              - gemfiles/activerecord_3_0.gemfile
         
     | 
| 
      
 6 
     | 
    
         
            +
              - gemfiles/activerecord_3_1.gemfile
         
     | 
| 
      
 7 
     | 
    
         
            +
              - gemfiles/activerecord_3_2.gemfile
         
     | 
| 
      
 8 
     | 
    
         
            +
              - gemfiles/activerecord_4_0.gemfile
         
     | 
| 
      
 9 
     | 
    
         
            +
            language: ruby
         
     | 
| 
      
 10 
     | 
    
         
            +
            matrix:
         
     | 
| 
      
 11 
     | 
    
         
            +
              allow_failures:
         
     | 
| 
      
 12 
     | 
    
         
            +
                - rvm: ruby-head
         
     | 
| 
      
 13 
     | 
    
         
            +
              include:
         
     | 
| 
      
 14 
     | 
    
         
            +
                - env: COVERAGE=1
         
     | 
| 
      
 15 
     | 
    
         
            +
                  gemfile: Gemfile
         
     | 
| 
      
 16 
     | 
    
         
            +
                  rvm: 2.1.0
         
     | 
| 
      
 17 
     | 
    
         
            +
            rvm:
         
     | 
| 
      
 18 
     | 
    
         
            +
              - 1.9.3
         
     | 
| 
      
 19 
     | 
    
         
            +
              - 2.0.0
         
     | 
| 
      
 20 
     | 
    
         
            +
              - 2.1.0
         
     | 
| 
      
 21 
     | 
    
         
            +
              - ruby-head
         
     | 
| 
      
 22 
     | 
    
         
            +
            script: bundle exec rspec
         
     | 
    
        data/CHANGELOG.md
    ADDED
    
    
    
        data/Gemfile
    ADDED
    
    
    
        data/README.rdoc
    CHANGED
    
    | 
         @@ -1,4 +1,10 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            =  
     | 
| 
      
 1 
     | 
    
         
            +
            = Vestal Versions
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            {<img src="https://badge.fury.io/rb/vestal_versions.png" alt="Gem Version" />}[http://badge.fury.io/rb/vestal_versions]
         
     | 
| 
      
 4 
     | 
    
         
            +
            {<img src="https://travis-ci.org/laserlemon/vestal_versions.png?branch=master" alt="Build Status" />}[https://travis-ci.org/laserlemon/vestal_versions]
         
     | 
| 
      
 5 
     | 
    
         
            +
            {<img src="https://codeclimate.com/github/laserlemon/vestal_versions.png" alt="Code Climate" />}[https://codeclimate.com/github/laserlemon/vestal_versions]
         
     | 
| 
      
 6 
     | 
    
         
            +
            {<img src="https://coveralls.io/repos/laserlemon/vestal_versions/badge.png" alt="Coverage Status" />}[https://coveralls.io/r/laserlemon/vestal_versions]
         
     | 
| 
      
 7 
     | 
    
         
            +
            {<img src="https://gemnasium.com/laserlemon/vestal_versions.png" alt="Dependency Status" />}[https://gemnasium.com/laserlemon/vestal_versions]
         
     | 
| 
       2 
8 
     | 
    
         | 
| 
       3 
9 
     | 
    
         
             
            Finally, DRY ActiveRecord versioning!
         
     | 
| 
       4 
10 
     | 
    
         | 
| 
         @@ -8,23 +14,23 @@ Finally, DRY ActiveRecord versioning! 
     | 
|
| 
       8 
14 
     | 
    
         | 
| 
       9 
15 
     | 
    
         
             
            And that's just what <tt>vestal_versions</tt> does. Not only can a model be reverted to a previous version number but also to a date or time!
         
     | 
| 
       10 
16 
     | 
    
         | 
| 
       11 
     | 
    
         
            -
            ==  
     | 
| 
      
 17 
     | 
    
         
            +
            == Compatibility
         
     | 
| 
       12 
18 
     | 
    
         | 
| 
       13 
     | 
    
         
            -
             
     | 
| 
      
 19 
     | 
    
         
            +
            Tested with Active Record 3.2.16 with Ruby 1.9.3 and 1.9.2.
         
     | 
| 
       14 
20 
     | 
    
         | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
                ...
         
     | 
| 
       17 
     | 
    
         
            -
                config.gem 'vestal_versions'
         
     | 
| 
       18 
     | 
    
         
            -
                ...
         
     | 
| 
       19 
     | 
    
         
            -
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
            == Installation
         
     | 
| 
       20 
22 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
             
     | 
| 
      
 23 
     | 
    
         
            +
            In the Gemfile:
         
     | 
| 
       22 
24 
     | 
    
         | 
| 
       23 
     | 
    
         
            -
             
     | 
| 
      
 25 
     | 
    
         
            +
            ** Note: I am giving this project some much needed love to keep her relevant in a post Rails 3 world. I will be finalizing a version to support 1.9.2+ and Rails 3.2+ soon and pushing the gem, till then, use the git repo:
         
     | 
| 
      
 26 
     | 
    
         
            +
            ~dreamr
         
     | 
| 
      
 27 
     | 
    
         
            +
              
         
     | 
| 
      
 28 
     | 
    
         
            +
              gem 'vestal_versions', :git => 'git://github.com/laserlemon/vestal_versions'
         
     | 
| 
      
 29 
     | 
    
         
            +
              
         
     | 
| 
       24 
30 
     | 
    
         | 
| 
       25 
31 
     | 
    
         
             
            Next, generate and run the first and last versioning migration you'll ever need:
         
     | 
| 
       26 
32 
     | 
    
         | 
| 
       27 
     | 
    
         
            -
              $  
     | 
| 
      
 33 
     | 
    
         
            +
              $ rails generate vestal_versions:migration
         
     | 
| 
       28 
34 
     | 
    
         
             
              $ rake db:migrate
         
     | 
| 
       29 
35 
     | 
    
         | 
| 
       30 
36 
     | 
    
         
             
            == Example
         
     | 
| 
         @@ -33,9 +39,9 @@ To version an ActiveRecord model, simply add <tt>versioned</tt> to your class li 
     | 
|
| 
       33 
39 
     | 
    
         | 
| 
       34 
40 
     | 
    
         
             
              class User < ActiveRecord::Base
         
     | 
| 
       35 
41 
     | 
    
         
             
                versioned
         
     | 
| 
       36 
     | 
    
         
            -
             
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
       37 
43 
     | 
    
         
             
                validates_presence_of :first_name, :last_name
         
     | 
| 
       38 
     | 
    
         
            -
             
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
       39 
45 
     | 
    
         
             
                def name
         
     | 
| 
       40 
46 
     | 
    
         
             
                  "#{first_name} #{last_name}"
         
     | 
| 
       41 
47 
     | 
    
         
             
                end
         
     | 
| 
         @@ -81,25 +87,25 @@ It's that easy! Now watch it in action... 
     | 
|
| 
       81 
87 
     | 
    
         
             
            For the most part, version 1.0 of <tt>vestal_versions</tt> is backwards compatible, with just a few notable changes:
         
     | 
| 
       82 
88 
     | 
    
         | 
| 
       83 
89 
     | 
    
         
             
            * The versions table has been beefed up. You'll need to add the following columns (and indexes, if you feel so inclined):
         
     | 
| 
       84 
     | 
    
         
            -
             
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
       85 
91 
     | 
    
         
             
                change_table :versions do |t|
         
     | 
| 
       86 
92 
     | 
    
         
             
                  t.belongs_to :user, :polymorphic => true
         
     | 
| 
       87 
93 
     | 
    
         
             
                  t.string :user_name
         
     | 
| 
       88 
94 
     | 
    
         
             
                  t.string :tag
         
     | 
| 
       89 
95 
     | 
    
         
             
                end
         
     | 
| 
       90 
     | 
    
         
            -
             
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
       91 
97 
     | 
    
         
             
                change_table :versions do |t|
         
     | 
| 
       92 
98 
     | 
    
         
             
                  t.index [:user_id, :user_type]
         
     | 
| 
       93 
99 
     | 
    
         
             
                  t.index :user_name
         
     | 
| 
       94 
100 
     | 
    
         
             
                  t.index :tag
         
     | 
| 
       95 
101 
     | 
    
         
             
                end
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
      
 102 
     | 
    
         
            +
             
     | 
| 
       97 
103 
     | 
    
         
             
            * When a model is created (or updated the first time after being versioned), an initial version record with a number of 1 is no longer created. These aren't used during reversion and so they end up just being dead weight. Feel free to scrap all your versions where <tt>number == 1</tt> after the upgrade if you'd like to free up some room in your database (but you don't have to).
         
     | 
| 
       98 
     | 
    
         
            -
             
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
       99 
105 
     | 
    
         
             
            * Models that have no version records in the database will return a <tt>@user.version</tt> of 1. In the past, this would have returned <tt>nil</tt> instead.
         
     | 
| 
       100 
     | 
    
         
            -
             
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
       101 
107 
     | 
    
         
             
            * <tt>Version</tt> has moved to <tt>VestalVersions::Version</tt> to make way for custom version classes.
         
     | 
| 
       102 
     | 
    
         
            -
             
     | 
| 
      
 108 
     | 
    
         
            +
             
     | 
| 
       103 
109 
     | 
    
         
             
            * <tt>Version#version</tt> did not survive the move to <tt>VestalVersions::Version#version</tt>. That alias was dropped (too confusing). Use <tt>VestalVersions::Version#number</tt>.
         
     | 
| 
       104 
110 
     | 
    
         | 
| 
       105 
111 
     | 
    
         
             
            == New to 1.0
         
     | 
| 
         @@ -107,7 +113,7 @@ For the most part, version 1.0 of <tt>vestal_versions</tt> is backwards compatib 
     | 
|
| 
       107 
113 
     | 
    
         
             
            There are a handful of exciting new additions in version 1.0 of <tt>vestal_versions</tt>. A lot has changed in the code: much better documentation, more modular organization of features, and a more exhaustive test suite. But there are also a number of new features that are available in this release of <tt>vestal_versions</tt>:
         
     | 
| 
       108 
114 
     | 
    
         | 
| 
       109 
115 
     | 
    
         
             
            * The ability to completely skip versioning within a new <tt>skip_version</tt> block:
         
     | 
| 
       110 
     | 
    
         
            -
             
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
       111 
117 
     | 
    
         
             
                @user.version # => 1
         
     | 
| 
       112 
118 
     | 
    
         
             
                @user.skip_version do
         
     | 
| 
       113 
119 
     | 
    
         
             
                  @user.update_attribute(:first_name, "Stephen")
         
     | 
| 
         @@ -116,11 +122,11 @@ There are a handful of exciting new additions in version 1.0 of <tt>vestal_versi 
     | 
|
| 
       116 
122 
     | 
    
         
             
                  @user.update_attributes(:last_name => "Jobs")
         
     | 
| 
       117 
123 
     | 
    
         
             
                end
         
     | 
| 
       118 
124 
     | 
    
         
             
                @user.version # => 1
         
     | 
| 
       119 
     | 
    
         
            -
             
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
       120 
126 
     | 
    
         
             
              Also available, are <tt>merge_version</tt> and <tt>append_version</tt> blocks. The <tt>merge_version</tt> block will compile the possibly multiple versions that would result from the updates inside the block into one summary version. The single resulting version is then tacked onto the version history as usual. The <tt>append_version</tt> block works similarly except that the resulting single version is combined with the most recent version in the history and saved.
         
     | 
| 
       121 
     | 
    
         
            -
             
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
       122 
128 
     | 
    
         
             
            * Version tagging. Any version can have a tag attached to it (must be unique within the scope of the versioned parent) and that tag can be used for reversion.
         
     | 
| 
       123 
     | 
    
         
            -
             
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
       124 
130 
     | 
    
         
             
                @user.name # => "Steve Richert"
         
     | 
| 
       125 
131 
     | 
    
         
             
                @user.update_attribute(:last_name, "Jobs")
         
     | 
| 
       126 
132 
     | 
    
         
             
                @user.name # => "Steve Jobs"
         
     | 
| 
         @@ -129,11 +135,11 @@ There are a handful of exciting new additions in version 1.0 of <tt>vestal_versi 
     | 
|
| 
       129 
135 
     | 
    
         
             
                @user.name # => "Steve Richert"
         
     | 
| 
       130 
136 
     | 
    
         
             
                @user.revert_to("apple")
         
     | 
| 
       131 
137 
     | 
    
         
             
                @user.name # => "Steve Jobs"
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
      
 138 
     | 
    
         
            +
             
     | 
| 
       133 
139 
     | 
    
         
             
              So if you're not big on version numbers, you could just tag your versions and avoid the numbers altogether.
         
     | 
| 
       134 
     | 
    
         
            -
             
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
       135 
141 
     | 
    
         
             
            * Resetting. This is basically a hard revert. The new <tt>reset_to!</tt> instance method behaves just like the <tt>revert_to!</tt> method except that after the reversion, it will also scrap all the versions that came after that target version.
         
     | 
| 
       136 
     | 
    
         
            -
             
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
       137 
143 
     | 
    
         
             
                @user.name # => "Steve Richert"
         
     | 
| 
       138 
144 
     | 
    
         
             
                @user.version # => 1
         
     | 
| 
       139 
145 
     | 
    
         
             
                @user.versions.count # => 0
         
     | 
| 
         @@ -145,29 +151,50 @@ There are a handful of exciting new additions in version 1.0 of <tt>vestal_versi 
     | 
|
| 
       145 
151 
     | 
    
         
             
                @user.name # => "Steve Richert"
         
     | 
| 
       146 
152 
     | 
    
         
             
                @user.version # => 1
         
     | 
| 
       147 
153 
     | 
    
         
             
                @user.versions.count # => 0
         
     | 
| 
       148 
     | 
    
         
            -
             
     | 
| 
      
 154 
     | 
    
         
            +
             
     | 
| 
       149 
155 
     | 
    
         
             
            * Storing which user is responsible for a revision. Rather than introduce a lot of controller magic to guess what to store, you can simply update an additional attribute on your versioned model: <tt>updated_by</tt>.
         
     | 
| 
       150 
     | 
    
         
            -
             
     | 
| 
      
 156 
     | 
    
         
            +
             
     | 
| 
       151 
157 
     | 
    
         
             
                @user.update_attributes(:last_name => "Jobs", :updated_by => "Tyler")
         
     | 
| 
       152 
158 
     | 
    
         
             
                @user.versions.last.user # => "Tyler"
         
     | 
| 
       153 
     | 
    
         
            -
             
     | 
| 
      
 159 
     | 
    
         
            +
             
     | 
| 
       154 
160 
     | 
    
         
             
              Instead of passing a simple string to the <tt>updated_by</tt> setter, you can pass a model instance, such as an ActiveRecord user or administrator. The association will be saved polymorphically alongside the version.
         
     | 
| 
       155 
     | 
    
         
            -
             
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
       156 
162 
     | 
    
         
             
                @user.update_attributes(:last_name => "Jobs", :updated_by => current_user)
         
     | 
| 
       157 
163 
     | 
    
         
             
                @user.versions.last.user # => #<User first_name: "Steven", last_name: "Tyler">
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
      
 164 
     | 
    
         
            +
             
     | 
| 
       159 
165 
     | 
    
         
             
            * Global configuration. The new <tt>vestal_versions</tt> Rails generator also writes an initializer with instructions on how to set application-wide options for the <tt>versioned</tt> method.
         
     | 
| 
       160 
     | 
    
         
            -
             
     | 
| 
      
 166 
     | 
    
         
            +
             
     | 
| 
       161 
167 
     | 
    
         
             
            * Conditional version creation. The <tt>versioned</tt> method now accepts <tt>:if</tt> and <tt>:unless</tt> options. Each expects a symbol representing an instance method or a proc that will be evaluated to determine whether or not to create a new version after an update. An array containing any combination of symbols and procs can also be given.
         
     | 
| 
       162 
     | 
    
         
            -
             
     | 
| 
      
 168 
     | 
    
         
            +
             
     | 
| 
       163 
169 
     | 
    
         
             
                class User < ActiveRecord::Base
         
     | 
| 
       164 
170 
     | 
    
         
             
                  versioned :if => :really_create_a_version?
         
     | 
| 
       165 
171 
     | 
    
         
             
                end
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
      
 172 
     | 
    
         
            +
             
     | 
| 
       167 
173 
     | 
    
         
             
            * Custom version classes. By passing a <tt>:class_name</tt> option to the <tt>versioned</tt> method, you can specify your own ActiveRecord version model. <tt>VestalVersions::Version</tt> is the default, but feel free to stray from that. I recommend that your custom model inherit from <tt>VestalVersions::Version</tt>, but that's up to you!
         
     | 
| 
       168 
     | 
    
         
            -
             
     | 
| 
      
 174 
     | 
    
         
            +
             
     | 
| 
       169 
175 
     | 
    
         
             
            * A <tt>versioned?</tt> convenience class method. If your user model is versioned, <tt>User.versioned?</tt> will let you know.
         
     | 
| 
       170 
     | 
    
         
            -
             
     | 
| 
      
 176 
     | 
    
         
            +
             
     | 
| 
      
 177 
     | 
    
         
            +
            * Soft Deletes & Restoration.  By setting <tt>:dependent</tt> to <tt>:tracking</tt> destroys will be tracked.  On destroy a new version will be created storing the complete details of the object with a tag of 'deleted'.  The object can later be restored using the <tt>restore!</tt> method on the VestalVersions::Version record.  The attributes of the restored object will be set using the attribute writer methods.  After a restore! is performed the version record with the 'deleted' tag is removed from the history.
         
     | 
| 
      
 178 
     | 
    
         
            +
             
     | 
| 
      
 179 
     | 
    
         
            +
                class User < ActiveRecord::Base
         
     | 
| 
      
 180 
     | 
    
         
            +
                  versioned :dependent => :tracking
         
     | 
| 
      
 181 
     | 
    
         
            +
                end
         
     | 
| 
      
 182 
     | 
    
         
            +
             
     | 
| 
      
 183 
     | 
    
         
            +
                >> @user.version
         
     | 
| 
      
 184 
     | 
    
         
            +
                => 2
         
     | 
| 
      
 185 
     | 
    
         
            +
                >> @user.destroy
         
     | 
| 
      
 186 
     | 
    
         
            +
                => <User id: 2, first_name: "Steve", last_name: "Jobs", ... >
         
     | 
| 
      
 187 
     | 
    
         
            +
                >> User.find(2)
         
     | 
| 
      
 188 
     | 
    
         
            +
                => ActiveRecord::RecordNotFound: Couldn't find User with ID=2
         
     | 
| 
      
 189 
     | 
    
         
            +
                >> VestalVersions::Version.last
         
     | 
| 
      
 190 
     | 
    
         
            +
                => <VestalVersions::Version id: 4, versioned_id: 2, versioned_type: "User", user_id: nil, user_type: nil, user_name: nil, modifications: {"created_at"=>Sun Aug 01 18:39:57 UTC 2010, "updated_at"=>Sun Aug 01 18:42:28 UTC 2010, "id"=>2, "last_name"=>"Jobs", "first_name"=>"Stephen"}, number: 3, tag: "deleted", created_at: "2010-08-01 18:42:43", updated_at: "2010-08-01 18:42:43">
         
     | 
| 
      
 191 
     | 
    
         
            +
                >> VestalVersions::Version.last.restore!
         
     | 
| 
      
 192 
     | 
    
         
            +
                => <User id: 2, first_name => "Steven", last_name: "Jobs", ... >
         
     | 
| 
      
 193 
     | 
    
         
            +
                >> @user = User.find(2)
         
     | 
| 
      
 194 
     | 
    
         
            +
                => <User id: 2, first_name => "Steven", last_name: "Jobs", ... >
         
     | 
| 
      
 195 
     | 
    
         
            +
                >> @user.version
         
     | 
| 
      
 196 
     | 
    
         
            +
                => 2
         
     | 
| 
      
 197 
     | 
    
         
            +
             
     | 
| 
       171 
198 
     | 
    
         
             
            == Thanks!
         
     | 
| 
       172 
199 
     | 
    
         | 
| 
       173 
200 
     | 
    
         
             
            Thank you to all those who post {issues and suggestions}[http://github.com/laserlemon/vestal_versions/issues]. And special thanks to:
         
     | 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,45 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require ' 
     | 
| 
       2 
     | 
    
         
            -
            require ' 
     | 
| 
       3 
     | 
    
         
            -
            require 'rake/testtask'
         
     | 
| 
       4 
     | 
    
         
            -
            require 'rcov/rcovtask'
         
     | 
| 
       5 
     | 
    
         
            -
            require 'rake/rdoctask'
         
     | 
| 
      
 1 
     | 
    
         
            +
            require 'bundler/gem_tasks'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rspec/core/rake_task'
         
     | 
| 
       6 
3 
     | 
    
         | 
| 
       7 
     | 
    
         
            -
             
     | 
| 
       8 
     | 
    
         
            -
              require 'jeweler'
         
     | 
| 
       9 
     | 
    
         
            -
              Jeweler::Tasks.new do |g|
         
     | 
| 
       10 
     | 
    
         
            -
                g.name = 'vestal_versions'
         
     | 
| 
       11 
     | 
    
         
            -
                g.summary = %(Keep a DRY history of your ActiveRecord models' changes)
         
     | 
| 
       12 
     | 
    
         
            -
                g.description = %(Keep a DRY history of your ActiveRecord models' changes)
         
     | 
| 
       13 
     | 
    
         
            -
                g.email = 'steve@laserlemon.com'
         
     | 
| 
       14 
     | 
    
         
            -
                g.homepage = 'http://github.com/laserlemon/vestal_versions'
         
     | 
| 
       15 
     | 
    
         
            -
                g.authors = %w(laserlemon)
         
     | 
| 
       16 
     | 
    
         
            -
                g.add_dependency 'activerecord', '>= 2.1.0'
         
     | 
| 
       17 
     | 
    
         
            -
                g.add_development_dependency 'shoulda'
         
     | 
| 
       18 
     | 
    
         
            -
                g.add_development_dependency 'mocha'
         
     | 
| 
       19 
     | 
    
         
            -
              end
         
     | 
| 
       20 
     | 
    
         
            -
              Jeweler::GemcutterTasks.new
         
     | 
| 
       21 
     | 
    
         
            -
            rescue LoadError
         
     | 
| 
       22 
     | 
    
         
            -
              puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
         
     | 
| 
       23 
     | 
    
         
            -
            end
         
     | 
| 
      
 4 
     | 
    
         
            +
            RSpec::Core::RakeTask.new(:spec)
         
     | 
| 
       24 
5 
     | 
    
         | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
     | 
    
         
            -
              t.libs = %w(test)
         
     | 
| 
       27 
     | 
    
         
            -
              t.pattern = 'test/**/*_test.rb'
         
     | 
| 
       28 
     | 
    
         
            -
            end
         
     | 
| 
       29 
     | 
    
         
            -
             
     | 
| 
       30 
     | 
    
         
            -
            Rcov::RcovTask.new do |t|
         
     | 
| 
       31 
     | 
    
         
            -
              t.libs = %w(test)
         
     | 
| 
       32 
     | 
    
         
            -
              t.pattern = 'test/**/*_test.rb'
         
     | 
| 
       33 
     | 
    
         
            -
            end
         
     | 
| 
       34 
     | 
    
         
            -
             
     | 
| 
       35 
     | 
    
         
            -
            task :test => :check_dependencies
         
     | 
| 
       36 
     | 
    
         
            -
            task :default => :test
         
     | 
| 
       37 
     | 
    
         
            -
             
     | 
| 
       38 
     | 
    
         
            -
            Rake::RDocTask.new do |r|
         
     | 
| 
       39 
     | 
    
         
            -
              version = File.exist?('VERSION') ? File.read('VERSION') : nil
         
     | 
| 
       40 
     | 
    
         
            -
              r.rdoc_dir = 'rdoc'
         
     | 
| 
       41 
     | 
    
         
            -
              r.title = ['vestal_versions', version].compact.join(' ')
         
     | 
| 
       42 
     | 
    
         
            -
              r.options << '--line-numbers' << '--inline-source'
         
     | 
| 
       43 
     | 
    
         
            -
              r.rdoc_files.include('README*')
         
     | 
| 
       44 
     | 
    
         
            -
              r.rdoc_files.include('lib/**/*.rb')
         
     | 
| 
       45 
     | 
    
         
            -
            end
         
     | 
| 
      
 6 
     | 
    
         
            +
            task :default => :spec
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'rails/generators/named_base'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            module VestalVersions
         
     | 
| 
      
 4 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 5 
     | 
    
         
            +
                module Base
         
     | 
| 
      
 6 
     | 
    
         
            +
                  def source_root
         
     | 
| 
      
 7 
     | 
    
         
            +
                    @_vestal_versions_source_root ||= File.expand_path(File.join('../vestal_versions', generator_name, 'templates'), __FILE__)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  end
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'generators/vestal_versions'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'rails/generators/active_record'
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
            module VestalVersions
         
     | 
| 
      
 5 
     | 
    
         
            +
              module Generators
         
     | 
| 
      
 6 
     | 
    
         
            +
                class MigrationGenerator < ActiveRecord::Generators::Base
         
     | 
| 
      
 7 
     | 
    
         
            +
                  extend Base
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                  argument :name, :type => :string, :default => 'create_vestal_versions'
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def generate_files
         
     | 
| 
      
 12 
     | 
    
         
            +
                    migration_template 'migration.rb', "db/migrate/#{name}"
         
     | 
| 
      
 13 
     | 
    
         
            +
                    template 'initializer.rb', 'config/initializers/vestal_versions.rb'
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         
            File without changes
         
     | 
    
        data/{generators/vestal_versions → lib/generators/vestal_versions/migration}/templates/migration.rb
    RENAMED
    
    | 
         @@ -3,10 +3,11 @@ class CreateVestalVersions < ActiveRecord::Migration 
     | 
|
| 
       3 
3 
     | 
    
         
             
                create_table :versions do |t|
         
     | 
| 
       4 
4 
     | 
    
         
             
                  t.belongs_to :versioned, :polymorphic => true
         
     | 
| 
       5 
5 
     | 
    
         
             
                  t.belongs_to :user, :polymorphic => true
         
     | 
| 
       6 
     | 
    
         
            -
                  t.string 
     | 
| 
       7 
     | 
    
         
            -
                  t.text 
     | 
| 
      
 6 
     | 
    
         
            +
                  t.string  :user_name
         
     | 
| 
      
 7 
     | 
    
         
            +
                  t.text    :modifications
         
     | 
| 
       8 
8 
     | 
    
         
             
                  t.integer :number
         
     | 
| 
       9 
     | 
    
         
            -
                  t. 
     | 
| 
      
 9 
     | 
    
         
            +
                  t.integer :reverted_from
         
     | 
| 
      
 10 
     | 
    
         
            +
                  t.string  :tag
         
     | 
| 
       10 
11 
     | 
    
         | 
| 
       11 
12 
     | 
    
         
             
                  t.timestamps
         
     | 
| 
       12 
13 
     | 
    
         
             
                end
         
     | 
    
        data/lib/vestal_versions.rb
    CHANGED
    
    | 
         @@ -1,3 +1,8 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/concern'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_support/dependencies/autoload'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'active_support/core_ext/module/delegation'
         
     | 
| 
      
 4 
     | 
    
         
            +
            require 'active_record'
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
       1 
6 
     | 
    
         
             
            # +vestal_versions+ keeps track of updates to ActiveRecord models, leveraging the introduction of
         
     | 
| 
       2 
7 
     | 
    
         
             
            # dirty attributes in Rails 2.1. By storing only the updated attributes in a serialized column of a
         
     | 
| 
       3 
8 
     | 
    
         
             
            # single version model, the history is kept DRY and no additional schema changes are necessary.
         
     | 
| 
         @@ -21,16 +26,34 @@ 
     | 
|
| 
       21 
26 
     | 
    
         
             
            #
         
     | 
| 
       22 
27 
     | 
    
         
             
            # See the +versioned+ documentation for more details.
         
     | 
| 
       23 
28 
     | 
    
         | 
| 
       24 
     | 
    
         
            -
            Dir[File.join(File.dirname(__FILE__), 'vestal_versions', '*.rb')].each{|f| require f }
         
     | 
| 
       25 
     | 
    
         
            -
             
     | 
| 
       26 
29 
     | 
    
         
             
            # The base module that gets included in ActiveRecord::Base. See the documentation for
         
     | 
| 
       27 
30 
     | 
    
         
             
            # VestalVersions::ClassMethods for more useful information.
         
     | 
| 
       28 
31 
     | 
    
         
             
            module VestalVersions
         
     | 
| 
       29 
     | 
    
         
            -
               
     | 
| 
       30 
     | 
    
         
            -
             
     | 
| 
       31 
     | 
    
         
            -
             
     | 
| 
       32 
     | 
    
         
            -
             
     | 
| 
       33 
     | 
    
         
            -
             
     | 
| 
      
 32 
     | 
    
         
            +
              extend ActiveSupport::Concern
         
     | 
| 
      
 33 
     | 
    
         
            +
              extend ActiveSupport::Autoload
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              autoload :Changes
         
     | 
| 
      
 36 
     | 
    
         
            +
              autoload :Conditions
         
     | 
| 
      
 37 
     | 
    
         
            +
              autoload :Control
         
     | 
| 
      
 38 
     | 
    
         
            +
              autoload :Creation
         
     | 
| 
      
 39 
     | 
    
         
            +
              autoload :Deletion
         
     | 
| 
      
 40 
     | 
    
         
            +
              autoload :Options
         
     | 
| 
      
 41 
     | 
    
         
            +
              autoload :Reload
         
     | 
| 
      
 42 
     | 
    
         
            +
              autoload :Reset
         
     | 
| 
      
 43 
     | 
    
         
            +
              autoload :Reversion
         
     | 
| 
      
 44 
     | 
    
         
            +
              autoload :Users
         
     | 
| 
      
 45 
     | 
    
         
            +
              autoload :Version
         
     | 
| 
      
 46 
     | 
    
         
            +
              autoload :VERSION, 'vestal_versions/version_num'
         
     | 
| 
      
 47 
     | 
    
         
            +
              autoload :VersionTagging
         
     | 
| 
      
 48 
     | 
    
         
            +
              autoload :Versioned
         
     | 
| 
      
 49 
     | 
    
         
            +
              autoload :Versions
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
              class << self
         
     | 
| 
      
 52 
     | 
    
         
            +
                delegate :config, :configure, :to => Version
         
     | 
| 
      
 53 
     | 
    
         
            +
              end
         
     | 
| 
      
 54 
     | 
    
         
            +
             
     | 
| 
      
 55 
     | 
    
         
            +
              included do
         
     | 
| 
      
 56 
     | 
    
         
            +
                include Versioned
         
     | 
| 
       34 
57 
     | 
    
         
             
              end
         
     | 
| 
       35 
58 
     | 
    
         | 
| 
       36 
59 
     | 
    
         
             
              module ClassMethods
         
     | 
| 
         @@ -46,7 +69,9 @@ module VestalVersions 
     | 
|
| 
       46 
69 
     | 
    
         
             
                #   will permanently remove all associated versions *without* triggering any destroy callbacks.
         
     | 
| 
       47 
70 
     | 
    
         
             
                #   Other options are :destroy which removes the associated versions *with* callbacks, or
         
     | 
| 
       48 
71 
     | 
    
         
             
                #   :nullify which leaves the version records in the database, but dissociates them from the
         
     | 
| 
       49 
     | 
    
         
            -
                #   parent object by setting the foreign key columns to +nil+ values.
         
     | 
| 
      
 72 
     | 
    
         
            +
                #   parent object by setting the foreign key columns to +nil+ values.  Setting this option to 
         
     | 
| 
      
 73 
     | 
    
         
            +
                #   :tracking will perform a soft delete on destroy and create a new version record preserving
         
     | 
| 
      
 74 
     | 
    
         
            +
                #   details of this record for later restoration.
         
     | 
| 
       50 
75 
     | 
    
         
             
                # * <tt>:except</tt>: An update will trigger version creation as long as at least one column
         
     | 
| 
       51 
76 
     | 
    
         
             
                #   outside those specified here was updated. Also, upon version creation, the columns
         
     | 
| 
       52 
77 
     | 
    
         
             
                #   specified here will be excluded from the change history. This is useful when dealing with
         
     | 
| 
         @@ -63,6 +88,9 @@ module VestalVersions 
     | 
|
| 
       63 
88 
     | 
    
         
             
                #   object is updated to determine whether a new version should be created. +to_proc+ is called
         
     | 
| 
       64 
89 
     | 
    
         
             
                #   on any symbols given and the resulting procs are called, passing in the object itself. If
         
     | 
| 
       65 
90 
     | 
    
         
             
                #   an array is given, all must be evaluate to +true+ in order for a version to be created.
         
     | 
| 
      
 91 
     | 
    
         
            +
                # * <tt>:initial_version</tt>: When set to true, an initial version is always created when the
         
     | 
| 
      
 92 
     | 
    
         
            +
                #   parent object is created. This initial version will have nil changes however it can be
         
     | 
| 
      
 93 
     | 
    
         
            +
                #   used to store who created the original version.
         
     | 
| 
       66 
94 
     | 
    
         
             
                # * <tt>:only</tt>: An update will trigger version creation as long as at least one updated
         
     | 
| 
       67 
95 
     | 
    
         
             
                #   column falls within those specified here. Also, upon version creation, only the columns
         
     | 
| 
       68 
96 
     | 
    
         
             
                #   specified here will be included in the change history. This option accepts a symbol, string
         
     | 
| 
         @@ -85,15 +113,14 @@ module VestalVersions 
     | 
|
| 
       85 
113 
     | 
    
         
             
                  include Reset
         
     | 
| 
       86 
114 
     | 
    
         
             
                  include Conditions
         
     | 
| 
       87 
115 
     | 
    
         
             
                  include Control
         
     | 
| 
       88 
     | 
    
         
            -
                  include  
     | 
| 
      
 116 
     | 
    
         
            +
                  include VersionTagging
         
     | 
| 
       89 
117 
     | 
    
         
             
                  include Reload
         
     | 
| 
      
 118 
     | 
    
         
            +
                  include Deletion
         
     | 
| 
       90 
119 
     | 
    
         | 
| 
       91 
120 
     | 
    
         
             
                  prepare_versioned_options(options)
         
     | 
| 
       92 
121 
     | 
    
         
             
                  has_many :versions, options, &block
         
     | 
| 
       93 
122 
     | 
    
         
             
                end
         
     | 
| 
       94 
123 
     | 
    
         
             
              end
         
     | 
| 
       95 
     | 
    
         
            -
             
     | 
| 
       96 
     | 
    
         
            -
              extend Configuration
         
     | 
| 
       97 
124 
     | 
    
         
             
            end
         
     | 
| 
       98 
125 
     | 
    
         | 
| 
       99 
     | 
    
         
            -
            ActiveRecord::Base. 
     | 
| 
      
 126 
     | 
    
         
            +
            ActiveRecord::Base.class_eval{ include VestalVersions }
         
     |