active_versioning 0.1.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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/README.md +140 -0
- data/Rakefile +6 -0
- data/active_versioning.gemspec +34 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/circle.yml +6 -0
- data/lib/active_versioning/errors/incompatible_version.rb +12 -0
- data/lib/active_versioning/errors.rb +8 -0
- data/lib/active_versioning/events.rb +13 -0
- data/lib/active_versioning/model/version_proxy.rb +119 -0
- data/lib/active_versioning/model/versioned.rb +73 -0
- data/lib/active_versioning/model.rb +37 -0
- data/lib/active_versioning/version.rb +3 -0
- data/lib/active_versioning/version_manager.rb +31 -0
- data/lib/active_versioning.rb +9 -0
- data/lib/generators/active_versioning_generator.rb +15 -0
- data/lib/generators/templates/migrations/create_versions.rb +18 -0
- data/lib/generators/templates/models/version.rb +3 -0
- metadata +207 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 372e09adffd4d458bf02a8f21790b4c0545c3654
|
4
|
+
data.tar.gz: d7d12be88770e3731fcda71a38dc8ccdee72ab50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7e60a689e0bb675c81617a4c1f585e2a7e9c609603608cb29aa2301af76c2d4586b91104d9cc20d7686e6730442fd472958d79a197cca27373f5a8d9322026b2
|
7
|
+
data.tar.gz: e9b46b96aade3689dddcd4de01b089d75316e8c478d129e2e9a71d31abd613b5b177230cd8de9f9e4a3095be2ac48ee3ff09df6e41f564ac2cd27c77912632c3
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,140 @@
|
|
1
|
+
# ActiveVersioning
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/active_versioning) [](https://codeclimate.com/github/vigetlabs/active_versioning) [](https://codeclimate.com/github/vigetlabs/active_versioning/coverage) [](https://circleci.com/gh/vigetlabs/active_versioning)
|
4
|
+
|
5
|
+
ActiveVersioning provides out-of-the-box versioning functionality in Rails. ActiveVersioning serializes attributes when records are saved and allows for version and draft management.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem 'active_versioning'
|
13
|
+
```
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install active_versioning
|
22
|
+
|
23
|
+
Once installed, generate the necessary files and run migrations:
|
24
|
+
|
25
|
+
$ rails generate active_versioning
|
26
|
+
$ bundle exec rake db:migrate
|
27
|
+
|
28
|
+
## Setup
|
29
|
+
|
30
|
+
To set up versioning in your Rails app, include the following module in each model you'd like to version:
|
31
|
+
```ruby
|
32
|
+
class Post < ActiveRecord::Base
|
33
|
+
include ActiveVersioning::Model::Versioned
|
34
|
+
end
|
35
|
+
```
|
36
|
+
|
37
|
+
## Working with Drafts
|
38
|
+
|
39
|
+
`ActiveVersioning::Model::Versioned` provides a number of methods for accessing and working with versions.
|
40
|
+
|
41
|
+
To access the current draft of a record, use...
|
42
|
+
```ruby
|
43
|
+
draft = post.current_draft
|
44
|
+
```
|
45
|
+
This returns a proxy object to a draft version of the record, so you can treat it like the `post` itself -- making changes and either saving or updating.
|
46
|
+
```ruby
|
47
|
+
draft.title = 'New Title'
|
48
|
+
draft.save
|
49
|
+
|
50
|
+
# or..
|
51
|
+
|
52
|
+
draft.update(title: 'New Title')
|
53
|
+
```
|
54
|
+
Both `save` and `update` will make changes to the draft version of the post.
|
55
|
+
|
56
|
+
When you are ready to overwrite the record with its draft, use...
|
57
|
+
```ruby
|
58
|
+
draft.commit(committer: 'Bob', commit_message: 'Update post title.')
|
59
|
+
```
|
60
|
+
This changes our post's attributes to match those of the draft and then marks the draft as a committed version.
|
61
|
+
|
62
|
+
If you want to throw away a draft:
|
63
|
+
```ruby
|
64
|
+
post.destroy_draft
|
65
|
+
```
|
66
|
+
|
67
|
+
## Working with Versions
|
68
|
+
|
69
|
+
A draft is just a version with a particular state. To access all the versions for a particular record, use...
|
70
|
+
```ruby
|
71
|
+
post.versions # => All versions, whether the version state is 'create', 'draft', or 'commit'
|
72
|
+
post.versions.draft # => All draft versions
|
73
|
+
post.versions.committed # => All non-draft versions
|
74
|
+
post.versions.newest_first # => All versions starting with the most recently created
|
75
|
+
```
|
76
|
+
|
77
|
+
You can use any existing version to create a new draft:
|
78
|
+
```ruby
|
79
|
+
old_version = post.versions.committed.first
|
80
|
+
|
81
|
+
post.create_draft_from_version(old_version.id)
|
82
|
+
```
|
83
|
+
This will set `post.current_draft`'s attributes to the attributes stored in the given version's record. Returns boolean based on the save's success.
|
84
|
+
|
85
|
+
## Capturing Version Metadata
|
86
|
+
|
87
|
+
In addition to manually committing a version with a committer and commit message...
|
88
|
+
```ruby
|
89
|
+
post.current_draft.commit(committer: 'Bob', commit_message: 'Update post title.')
|
90
|
+
```
|
91
|
+
ActiveVersioning provides a `version_author` accessor on any versioned model, so you can capture the author for a record's initial create:
|
92
|
+
```ruby
|
93
|
+
post = Post.create(title: 'Title', body: 'Body text.', version_author: 'Bob')
|
94
|
+
|
95
|
+
post.versions.first.version_author # => 'Bob'
|
96
|
+
```
|
97
|
+
|
98
|
+
## Viewing and Modifying Versioned Attributes
|
99
|
+
|
100
|
+
If you want to see the attributes the are versioned, use...
|
101
|
+
```ruby
|
102
|
+
post.versioned_attributes # => { 'id' => 1, 'title' => 'Default Title' }
|
103
|
+
```
|
104
|
+
|
105
|
+
If you require additional versioned attributes, overwrite the `versioned_attribute_names` method in your model:
|
106
|
+
```ruby
|
107
|
+
class Post < ActiveRecord::Base
|
108
|
+
private
|
109
|
+
|
110
|
+
def versioned_attribute_names
|
111
|
+
super + %w(photo_id)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
```
|
115
|
+
|
116
|
+
## Handling Incompatible Versions
|
117
|
+
|
118
|
+
In the case of a versioned model that undergoes a schema change, all previous versions may reference attributes that no longer exist.
|
119
|
+
|
120
|
+
In ActiveVersioning, we consider these incompatible versions. An attempt to create a draft from an incompatible version will raise an error:
|
121
|
+
```
|
122
|
+
incompatible_version = post.versions.committed.last
|
123
|
+
|
124
|
+
incompatible_version.object
|
125
|
+
# => { 'deleted_attribute' => value }
|
126
|
+
|
127
|
+
post.create_draft_from_version(incompatible_version.id)
|
128
|
+
# => ActiveVersioning::Errors::IncompatibleVersion:
|
129
|
+
# The given version contains attributes that are no longer compatible with the current schema: deleted_attribute.
|
130
|
+
```
|
131
|
+
|
132
|
+
When rescued, the error object contains a reference to the record and the incompatible version:
|
133
|
+
```
|
134
|
+
begin
|
135
|
+
post.create_draft_from_version(incompatible_version.id)
|
136
|
+
rescue ActiveVersioning::Errors::IncompatibleVersion => error
|
137
|
+
error.record # => our `post` record
|
138
|
+
error.version # => our `incompatible_version`
|
139
|
+
end
|
140
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require 'active_versioning/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = "active_versioning"
|
9
|
+
spec.version = ActiveVersioning::VERSION
|
10
|
+
spec.authors = ["Ryan Stenberg"]
|
11
|
+
spec.email = ["ryan.stenberg@viget.com"]
|
12
|
+
|
13
|
+
spec.summary = "Plug-and-Play Versioning for Rails"
|
14
|
+
spec.description = "ActiveVersioning serializes attributes when records are saved and allows for version and draft management."
|
15
|
+
spec.homepage = "https://github.com/vigetlabs/active_versioning"
|
16
|
+
spec.license = "BSD"
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
19
|
+
spec.bindir = "exe"
|
20
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
21
|
+
spec.require_paths = ["lib"]
|
22
|
+
|
23
|
+
spec.add_dependency "rails", ">= 4.2.1"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", ">= 1.10"
|
26
|
+
spec.add_development_dependency "rake", ">= 10.0"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
spec.add_development_dependency "shoulda-matchers"
|
29
|
+
spec.add_development_dependency "database_cleaner"
|
30
|
+
spec.add_development_dependency "generator_spec"
|
31
|
+
spec.add_development_dependency "pry"
|
32
|
+
spec.add_development_dependency "sqlite3"
|
33
|
+
spec.add_development_dependency "codeclimate-test-reporter"
|
34
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "active_versioning"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/circle.yml
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
module ActiveVersioning
|
2
|
+
module Model
|
3
|
+
class VersionProxy < Delegator
|
4
|
+
#
|
5
|
+
# VersionProxy class
|
6
|
+
#
|
7
|
+
# Uses Ruby's Delegator class to delegate methods to the versioned
|
8
|
+
# resource. The bulk of this class overrides the Rails save, update, and
|
9
|
+
# reload methods to modify the record in the versions table as opposed
|
10
|
+
# to the versioned resource.
|
11
|
+
#
|
12
|
+
# A `commit` instance method writes to the versioned resource's record.
|
13
|
+
|
14
|
+
VersionInvalid = Class.new(StandardError)
|
15
|
+
|
16
|
+
attr_reader :version
|
17
|
+
|
18
|
+
def initialize(version)
|
19
|
+
@version = version
|
20
|
+
__setobj__(version.reify)
|
21
|
+
end
|
22
|
+
|
23
|
+
def __getobj__
|
24
|
+
@record
|
25
|
+
end
|
26
|
+
|
27
|
+
def __setobj__(record)
|
28
|
+
@record = record
|
29
|
+
end
|
30
|
+
|
31
|
+
# `class` should delegate to versioned resource, not return
|
32
|
+
# ActiveVersioning::Model::VersionProxy
|
33
|
+
undef class
|
34
|
+
|
35
|
+
def reload
|
36
|
+
__setobj__(version.reify)
|
37
|
+
end
|
38
|
+
|
39
|
+
def to_param
|
40
|
+
version.versionable.to_param
|
41
|
+
end
|
42
|
+
|
43
|
+
def save(*)
|
44
|
+
if valid?
|
45
|
+
version.update(version_attributes)
|
46
|
+
else
|
47
|
+
false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def save!(*)
|
52
|
+
if valid?
|
53
|
+
version.update!(version_attributes)
|
54
|
+
else
|
55
|
+
raise ::ActiveRecord::RecordInvalid.new(__getobj__)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def update(attributes)
|
60
|
+
raise draft_exception unless version.draft?
|
61
|
+
|
62
|
+
with_transaction_returning_status do
|
63
|
+
assign_attributes(attributes)
|
64
|
+
save
|
65
|
+
end
|
66
|
+
end
|
67
|
+
alias update_attributes update
|
68
|
+
|
69
|
+
def update!(attributes)
|
70
|
+
raise draft_exception unless version.draft?
|
71
|
+
|
72
|
+
with_transaction_returning_status do
|
73
|
+
assign_attributes(attributes)
|
74
|
+
save!
|
75
|
+
end
|
76
|
+
end
|
77
|
+
alias update_attributes! update!
|
78
|
+
|
79
|
+
def live?
|
80
|
+
false
|
81
|
+
end
|
82
|
+
|
83
|
+
def version?
|
84
|
+
true
|
85
|
+
end
|
86
|
+
|
87
|
+
def commit(params = {})
|
88
|
+
raise draft_exception unless version.draft?
|
89
|
+
|
90
|
+
attrs = version_attributes.tap do |attrs|
|
91
|
+
attrs.merge!(
|
92
|
+
draft: false,
|
93
|
+
event: ActiveVersioning::Events::COMMIT,
|
94
|
+
committed_at: Time.current
|
95
|
+
)
|
96
|
+
|
97
|
+
attrs.merge!(params)
|
98
|
+
end
|
99
|
+
|
100
|
+
version.update(attrs)
|
101
|
+
|
102
|
+
__getobj__.update(versioned_attributes)
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def draft_exception
|
108
|
+
ActiveVersioning::Errors::InvalidVersion.new("Version #{version.id} must be a draft")
|
109
|
+
end
|
110
|
+
|
111
|
+
def version_attributes
|
112
|
+
{
|
113
|
+
committer: version_author,
|
114
|
+
object: versioned_attributes
|
115
|
+
}
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ActiveVersioning
|
2
|
+
module Model
|
3
|
+
module Versioned
|
4
|
+
def self.included(base)
|
5
|
+
base.class_eval do
|
6
|
+
has_many :versions, -> { newest_first }, as: :versionable, dependent: :destroy
|
7
|
+
|
8
|
+
after_create :create_version!
|
9
|
+
|
10
|
+
attr_accessor :version_author
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def live?
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def version?
|
19
|
+
false
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_draft(force_reload = false)
|
23
|
+
unless persisted?
|
24
|
+
raise ActiveVersioning::Errors::RecordNotPersisted.new("#{self} must be persisted to create a draft version")
|
25
|
+
end
|
26
|
+
|
27
|
+
@current_draft = nil if force_reload
|
28
|
+
|
29
|
+
@current_draft ||= VersionProxy.new(versions.draft.first_or_create(
|
30
|
+
object: versioned_attributes,
|
31
|
+
event: 'draft'
|
32
|
+
))
|
33
|
+
end
|
34
|
+
|
35
|
+
def current_draft?
|
36
|
+
versions.draft.present?
|
37
|
+
end
|
38
|
+
|
39
|
+
def destroy_draft
|
40
|
+
versions.draft.destroy_all
|
41
|
+
end
|
42
|
+
|
43
|
+
def version_manager
|
44
|
+
@version_manager ||= VersionManager.new(self)
|
45
|
+
end
|
46
|
+
|
47
|
+
def create_draft_from_version(version_id)
|
48
|
+
version_manager.create_draft_from_version(version_id) and current_draft(true)
|
49
|
+
end
|
50
|
+
|
51
|
+
def versioned_attributes
|
52
|
+
versioned_attribute_names.reduce(Hash.new) do |attrs, name|
|
53
|
+
attrs.merge(name => send(name))
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def versioned_attribute_names
|
58
|
+
attribute_names - VersionManager::BLACKLISTED_ATTRIBUTES
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def create_version!
|
64
|
+
versions.create!(
|
65
|
+
event: ActiveVersioning::Events::CREATE,
|
66
|
+
committer: version_author,
|
67
|
+
committed_at: Time.current,
|
68
|
+
object: versioned_attributes
|
69
|
+
)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module ActiveVersioning
|
2
|
+
module Model
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
autoload :Versioned, 'active_versioning/model/versioned'
|
6
|
+
autoload :VersionProxy, 'active_versioning/model/version_proxy'
|
7
|
+
|
8
|
+
included do
|
9
|
+
belongs_to :versionable, polymorphic: true
|
10
|
+
|
11
|
+
serialize :object, Hash
|
12
|
+
|
13
|
+
validates :event, presence: true, inclusion: { in: ActiveVersioning::Events::ALL }
|
14
|
+
|
15
|
+
scope :newest_first, -> { order created_at: :desc }
|
16
|
+
scope :draft, -> { where draft: true }
|
17
|
+
scope :committed, -> { where draft: false }
|
18
|
+
|
19
|
+
def to_s
|
20
|
+
[
|
21
|
+
versionable.to_s,
|
22
|
+
committed_at.try(:utc).try(:strftime, '#%Y%m%d%H%M%S')
|
23
|
+
].compact.join(' ')
|
24
|
+
end
|
25
|
+
|
26
|
+
def reify
|
27
|
+
resource = versionable(true)
|
28
|
+
|
29
|
+
# Necessary to ensure resource and versionable are two distinct objects in memory
|
30
|
+
versionable(true)
|
31
|
+
|
32
|
+
resource.assign_attributes(object.slice(*resource.versioned_attribute_names))
|
33
|
+
resource
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module ActiveVersioning
|
2
|
+
class VersionManager < Struct.new(:record)
|
3
|
+
BLACKLISTED_ATTRIBUTES = %w(
|
4
|
+
created_at
|
5
|
+
updated_at
|
6
|
+
published
|
7
|
+
)
|
8
|
+
|
9
|
+
def create_draft_from_version(id)
|
10
|
+
version = record.versions.find(id)
|
11
|
+
|
12
|
+
ensure_compatibility_with(version)
|
13
|
+
|
14
|
+
new_version = record.versions.draft.first_or_create(event: 'draft')
|
15
|
+
new_version.object = version.object
|
16
|
+
new_version.save
|
17
|
+
end
|
18
|
+
|
19
|
+
def ensure_compatibility_with(version)
|
20
|
+
incompatible_attributes(version).tap do |incompatible_attrs|
|
21
|
+
if incompatible_attrs.any?
|
22
|
+
raise Errors::IncompatibleVersion.new(record, version), "The given version contains attributes that are no longer compatible with the current schema: #{incompatible_attrs.to_sentence}."
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def incompatible_attributes(version)
|
28
|
+
version.object.keys - record.attributes.keys
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'active_versioning/version'
|
2
|
+
require 'generators/active_versioning_generator'
|
3
|
+
|
4
|
+
module ActiveVersioning
|
5
|
+
autoload :Errors, 'active_versioning/errors'
|
6
|
+
autoload :Events, 'active_versioning/events'
|
7
|
+
autoload :Model, 'active_versioning/model'
|
8
|
+
autoload :VersionManager, 'active_versioning/version_manager'
|
9
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'rails/generators/active_record/migration'
|
2
|
+
|
3
|
+
class ActiveVersioningGenerator < Rails::Generators::Base
|
4
|
+
include ActiveRecord::Generators::Migration
|
5
|
+
|
6
|
+
source_root File.expand_path('../templates', __FILE__)
|
7
|
+
|
8
|
+
def install_models
|
9
|
+
copy_file 'models/version.rb', 'app/models/version.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
def install_migrations
|
13
|
+
migration_template 'migrations/create_versions.rb', 'db/migrate/create_versions.rb'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
class CreateVersions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :versions do |t|
|
4
|
+
t.string :versionable_type, null: false
|
5
|
+
t.integer :versionable_id, null: false
|
6
|
+
t.string :event, null: false
|
7
|
+
t.string :committer
|
8
|
+
t.text :object
|
9
|
+
t.boolean :draft, default: false
|
10
|
+
t.text :commit_message
|
11
|
+
t.datetime :committed_at
|
12
|
+
|
13
|
+
t.timestamps null: false
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index :versions, [:versionable_type, :versionable_id]
|
17
|
+
end
|
18
|
+
end
|
metadata
ADDED
@@ -0,0 +1,207 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: active_versioning
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ryan Stenberg
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-09-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 4.2.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 4.2.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.10'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.10'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: shoulda-matchers
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: database_cleaner
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: generator_spec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: pry
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: sqlite3
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: codeclimate-test-reporter
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
description: ActiveVersioning serializes attributes when records are saved and allows
|
154
|
+
for version and draft management.
|
155
|
+
email:
|
156
|
+
- ryan.stenberg@viget.com
|
157
|
+
executables: []
|
158
|
+
extensions: []
|
159
|
+
extra_rdoc_files: []
|
160
|
+
files:
|
161
|
+
- ".gitignore"
|
162
|
+
- ".rspec"
|
163
|
+
- ".travis.yml"
|
164
|
+
- Gemfile
|
165
|
+
- README.md
|
166
|
+
- Rakefile
|
167
|
+
- active_versioning.gemspec
|
168
|
+
- bin/console
|
169
|
+
- bin/setup
|
170
|
+
- circle.yml
|
171
|
+
- lib/active_versioning.rb
|
172
|
+
- lib/active_versioning/errors.rb
|
173
|
+
- lib/active_versioning/errors/incompatible_version.rb
|
174
|
+
- lib/active_versioning/events.rb
|
175
|
+
- lib/active_versioning/model.rb
|
176
|
+
- lib/active_versioning/model/version_proxy.rb
|
177
|
+
- lib/active_versioning/model/versioned.rb
|
178
|
+
- lib/active_versioning/version.rb
|
179
|
+
- lib/active_versioning/version_manager.rb
|
180
|
+
- lib/generators/active_versioning_generator.rb
|
181
|
+
- lib/generators/templates/migrations/create_versions.rb
|
182
|
+
- lib/generators/templates/models/version.rb
|
183
|
+
homepage: https://github.com/vigetlabs/active_versioning
|
184
|
+
licenses:
|
185
|
+
- BSD
|
186
|
+
metadata: {}
|
187
|
+
post_install_message:
|
188
|
+
rdoc_options: []
|
189
|
+
require_paths:
|
190
|
+
- lib
|
191
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
192
|
+
requirements:
|
193
|
+
- - ">="
|
194
|
+
- !ruby/object:Gem::Version
|
195
|
+
version: '0'
|
196
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
|
+
requirements:
|
198
|
+
- - ">="
|
199
|
+
- !ruby/object:Gem::Version
|
200
|
+
version: '0'
|
201
|
+
requirements: []
|
202
|
+
rubyforge_project:
|
203
|
+
rubygems_version: 2.4.5
|
204
|
+
signing_key:
|
205
|
+
specification_version: 4
|
206
|
+
summary: Plug-and-Play Versioning for Rails
|
207
|
+
test_files: []
|