fast_versioning 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +64 -0
- data/Rakefile +37 -0
- data/app/models/fast_versioning/fast_version.rb +11 -0
- data/db/migrate/20160914161314_create_fast_versioning_fast_versions.rb +14 -0
- data/lib/fast_versioning.rb +10 -0
- data/lib/fast_versioning/engine.rb +5 -0
- data/lib/fast_versioning/fast_versioned.rb +29 -0
- data/lib/fast_versioning/paper_trail_extensions.rb +38 -0
- data/lib/fast_versioning/railtie.rb +9 -0
- data/lib/fast_versioning/tracked_attribute.rb +10 -0
- data/lib/fast_versioning/value_change.rb +40 -0
- metadata +112 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ec16ba1c62cf76eb3f01b223c8b567084a799353
|
4
|
+
data.tar.gz: 6608e3c92443c1839aa47ad671da34e72a0aab40
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 15f23487376caa1e310b64ab6397dc5a2ad348c9332a87a7e0303a9bf3477fc57c11fdebad1464ed7f0e0008cffdc9a25969833de10204e7d82bea48023fdb17
|
7
|
+
data.tar.gz: 6e7cd07ad4f9e4054b2287deb6e9dc7c42bbc842a4ae1261ce412ebf1477cb7e73fbc9f3b20c6fd28852f23f9f06e785106bad1b0f1ca1d82d309fefdedae815
|
data/README.md
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
Fast Versioning
|
2
|
+
===========
|
3
|
+
A [PaperTrail](https://github.com/airblade/paper_trail) extension for seamless fast key/value versioning of individual object attributes, which can be queried.
|
4
|
+
|
5
|
+
### Why?
|
6
|
+
|
7
|
+
PaperTrail stores version changes in one serialized column, which is great for keeping backups, undoing, etc. For querying and searching this is a real pain to use, and sometimes you need to track single column changes that you can query, use for statistics, quickly check last changes. You can also use Fast Versioning to track more complex object state changes!
|
8
|
+
|
9
|
+
### How?
|
10
|
+
We hook up to PaperTrail version creation, check if an object's tracked attribute changed and store any changes individually.
|
11
|
+
|
12
|
+
Installation
|
13
|
+
------------
|
14
|
+
1. Add to the Gemfile and bundle
|
15
|
+
```ruby
|
16
|
+
gem 'fast_versioning'
|
17
|
+
```
|
18
|
+
2. Install migrations
|
19
|
+
```shell
|
20
|
+
rake fast_versioning:install:migrations
|
21
|
+
```
|
22
|
+
|
23
|
+
Configuration
|
24
|
+
-------------
|
25
|
+
1. Include the concern in your model
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
include FastVersioning::FastVersioned
|
29
|
+
has_paper_trail
|
30
|
+
|
31
|
+
...
|
32
|
+
# define what you want to track
|
33
|
+
has_fast_versions(
|
34
|
+
:plan_id,
|
35
|
+
:plan_type,
|
36
|
+
status: {
|
37
|
+
billed_statements: Proc.new { |account| account.utility_statements.count },
|
38
|
+
static_value: 'text'
|
39
|
+
}
|
40
|
+
)
|
41
|
+
|
42
|
+
# plan_id - is a attribute
|
43
|
+
# plan_type - is a custom method
|
44
|
+
# status - defines an additional serialized meta apart from storing property change
|
45
|
+
```
|
46
|
+
|
47
|
+
Usage
|
48
|
+
-----
|
49
|
+
|
50
|
+
### samples
|
51
|
+
```ruby
|
52
|
+
your_model.fast_versions # get all fast versions
|
53
|
+
your_model.fast_versions_for(:plan_type) # get fast versions for given property - chain
|
54
|
+
your_model.fast_versions.last.version # get parent paper_trail version object
|
55
|
+
your_model.fast_versions.last.item # get changed item
|
56
|
+
your_model.fast_versions.last.name # property name
|
57
|
+
your_model.fast_versions.last.value # get value
|
58
|
+
your_model.fast_versions.last.prev_value # get value before the change
|
59
|
+
|
60
|
+
# query
|
61
|
+
your_model.fast_versions_for(:status).where(value: 'active').where(prev_value: 'incomplete')
|
62
|
+
```
|
63
|
+
|
64
|
+
An [Arcadia Power](http://www.arcadiapower.com) Project
|
data/Rakefile
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
begin
|
2
|
+
require 'bundler/setup'
|
3
|
+
rescue LoadError
|
4
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'rdoc/task'
|
8
|
+
|
9
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
10
|
+
rdoc.rdoc_dir = 'rdoc'
|
11
|
+
rdoc.title = 'FastVersioning'
|
12
|
+
rdoc.options << '--line-numbers'
|
13
|
+
rdoc.rdoc_files.include('README.md')
|
14
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
15
|
+
end
|
16
|
+
|
17
|
+
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
|
18
|
+
load 'rails/tasks/engine.rake'
|
19
|
+
|
20
|
+
|
21
|
+
load 'rails/tasks/statistics.rake'
|
22
|
+
|
23
|
+
|
24
|
+
|
25
|
+
require 'bundler/gem_tasks'
|
26
|
+
|
27
|
+
require 'rake/testtask'
|
28
|
+
|
29
|
+
Rake::TestTask.new(:test) do |t|
|
30
|
+
t.libs << 'lib'
|
31
|
+
t.libs << 'test'
|
32
|
+
t.pattern = 'test/**/*_test.rb'
|
33
|
+
t.verbose = false
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
task default: :test
|
@@ -0,0 +1,11 @@
|
|
1
|
+
module FastVersioning
|
2
|
+
class FastVersion < ActiveRecord::Base
|
3
|
+
belongs_to :item, polymorphic: true
|
4
|
+
belongs_to :whodunnit, polymorphic: true
|
5
|
+
belongs_to :version, class_name: 'PaperTrail::Version'
|
6
|
+
|
7
|
+
validates :version_id, uniqueness: { scope: :name }
|
8
|
+
|
9
|
+
serialize :meta, JSON
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateFastVersioningFastVersions < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :fast_versioning_fast_versions do |t|
|
4
|
+
t.references :item, polymorphic: true, index: { name: 'fast_version_item_index' }
|
5
|
+
t.references :whodunnit, polymorphic: true, index: { name: 'fast_version_whodunnit_index' }
|
6
|
+
t.integer :version_id, index: { name: 'fast_version_version_id_index' }
|
7
|
+
t.string :name, index: { name: 'fast_version_name_index' }
|
8
|
+
t.string :prev_value, index: { name: 'fast_version_prev_value_index' }
|
9
|
+
t.string :value, index: { name: 'fast_version_value_index' }
|
10
|
+
t.text :meta
|
11
|
+
t.datetime :created_at, index: { name: 'fast_version_created_at_index' }
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'paper_trail'
|
2
|
+
require 'fast_versioning/tracked_attribute'
|
3
|
+
require 'fast_versioning/fast_versioned'
|
4
|
+
require 'fast_versioning/value_change'
|
5
|
+
require 'fast_versioning/paper_trail_extensions'
|
6
|
+
require 'fast_versioning/railtie'
|
7
|
+
require 'fast_versioning/engine'
|
8
|
+
|
9
|
+
module FastVersioning
|
10
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module FastVersioning
|
2
|
+
module FastVersioned
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
has_many :fast_versions, class_name: 'FastVersioning::FastVersion', as: :item
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def has_fast_versions(*attributes, **meta)
|
11
|
+
define_method :fast_version_for do
|
12
|
+
processed_meta = *meta.deep_dup.tap do |item|
|
13
|
+
item.values.each do |v|
|
14
|
+
v.each { |i,j| v[i] = j.call(self) if j.respond_to?(:call) }
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
(attributes + processed_meta).map do |tracked|
|
19
|
+
FastVersioning::TrackedAttribute.new(*tracked)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def fast_versions_for(name)
|
26
|
+
fast_versions.where(name: name)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module FastVersioning
|
2
|
+
module PaperTrailExtensions
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
after_create :create_fast_versions
|
7
|
+
has_many :fast_versions, class_name: 'FastVersioning::FastVersion'
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_fast_versions
|
11
|
+
if item.respond_to?(:fast_version_for, true)
|
12
|
+
value_change = FastVersioning::ValueChange.new(version: self)
|
13
|
+
|
14
|
+
item.send(:fast_version_for).each do |tracked_attribute|
|
15
|
+
if value_change.value_was(tracked_attribute.name) != value_change.value_became(tracked_attribute.name)
|
16
|
+
fast_versions.create(
|
17
|
+
item_id: item_id,
|
18
|
+
item_type: item_type,
|
19
|
+
whodunnit_id: whodunnit.to_i,
|
20
|
+
whodunnit_type: whodunnit_type,
|
21
|
+
name: tracked_attribute.name,
|
22
|
+
value: value_change.value_became(tracked_attribute.name),
|
23
|
+
prev_value: value_change.value_was(tracked_attribute.name),
|
24
|
+
meta: tracked_attribute.meta,
|
25
|
+
created_at: created_at
|
26
|
+
)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
true
|
31
|
+
end
|
32
|
+
|
33
|
+
def recreate_fast_versions!
|
34
|
+
fast_versions.destroy_all
|
35
|
+
create_fast_versions
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module FastVersioning
|
2
|
+
class ValueChange
|
3
|
+
def initialize(version:)
|
4
|
+
@version = version
|
5
|
+
@item = version.item
|
6
|
+
end
|
7
|
+
|
8
|
+
def value_was(name)
|
9
|
+
if can_use_changeset?(name)
|
10
|
+
@version.changeset[name][0]
|
11
|
+
else
|
12
|
+
item_was.send(name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def value_became(name)
|
17
|
+
if can_use_changeset?(name)
|
18
|
+
@version.changeset[name][1]
|
19
|
+
else
|
20
|
+
item_became.send(name)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def can_use_changeset?(name)
|
27
|
+
@version.respond_to?(:changeset) && @version.changeset[name].present?
|
28
|
+
end
|
29
|
+
|
30
|
+
# TODO: support different paper_trail versions
|
31
|
+
def item_was
|
32
|
+
@item_was ||= @version.reify(dup: true) || @item.class.new
|
33
|
+
end
|
34
|
+
|
35
|
+
# TODO: support different paper_trail versions
|
36
|
+
def item_became
|
37
|
+
@item_became ||= @version.next.present? ? @version.next.reify(dup: true) : @item
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
metadata
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fast_versioning
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Arcadia Power
|
8
|
+
- Iwo Dziechciarow
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-09-23 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rails
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ">="
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '0'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '0'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: paper_trail
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - "~>"
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '4.2'
|
35
|
+
type: :runtime
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - "~>"
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '4.2'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: sqlite3
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ">="
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '0'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: rspec-rails
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
description: Fast versioning extension for paper_trail
|
71
|
+
email:
|
72
|
+
- engineering@arcadiapower.com
|
73
|
+
executables: []
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- app/models/fast_versioning/fast_version.rb
|
80
|
+
- db/migrate/20160914161314_create_fast_versioning_fast_versions.rb
|
81
|
+
- lib/fast_versioning.rb
|
82
|
+
- lib/fast_versioning/engine.rb
|
83
|
+
- lib/fast_versioning/fast_versioned.rb
|
84
|
+
- lib/fast_versioning/paper_trail_extensions.rb
|
85
|
+
- lib/fast_versioning/railtie.rb
|
86
|
+
- lib/fast_versioning/tracked_attribute.rb
|
87
|
+
- lib/fast_versioning/value_change.rb
|
88
|
+
homepage: https://github.com/ArcadiaPower/fast-versioning
|
89
|
+
licenses:
|
90
|
+
- MIT
|
91
|
+
metadata: {}
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
requirements:
|
98
|
+
- - ">="
|
99
|
+
- !ruby/object:Gem::Version
|
100
|
+
version: '0'
|
101
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
|
+
requirements:
|
103
|
+
- - ">="
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 2.5.1
|
109
|
+
signing_key:
|
110
|
+
specification_version: 4
|
111
|
+
summary: Fast versioning extension for paper_trail
|
112
|
+
test_files: []
|