webtranslateit-version_fu 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4871354c79d2e70b5f2730b4017bf48246025e650cb267f3114c31f732bc7a3d
4
+ data.tar.gz: a56e7c8a82be42f777c88bff3e9a18ff01005f8d539b05101f94242d06e99bb1
5
+ SHA512:
6
+ metadata.gz: 1deea4674b48d01e206ce24dcdfc70e95d707a90d1b0f6d6000f4726a17a0dce0546a140879a22dd7c2a33eb469a6410fe98c03e62a2708ee724b9b8d6a99da9
7
+ data.tar.gz: 51d15ca7c3090a5ce123e6f6dfa40020188c67a9dff77066797efea08b0a9e20a412954472e5297cae92161d80f4f68c5a90f84a551f76b3d92f98b3e9de5289
data/MIT-LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ == version_fu
2
+ Copyright (c) 2008-9 Jordan McKible
3
+
4
+ == acts_as_versioned
5
+ Copyright (c) 2005 Rick Olson
6
+ ====================================================================
7
+
8
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
9
+ this software and associated documentation files (the "Software"), to deal in
10
+ the Software without restriction, including without limitation the rights to
11
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
12
+ of the Software, and to permit persons to whom the Software is furnished to do
13
+ so, subject to the following conditions:
14
+
15
+ The above copyright notice and this permission notice shall be included in all
16
+ copies or substantial portions of the Software.
17
+
18
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,126 @@
1
+ # version_fu
2
+
3
+ [![Ruby](https://github.com/webtranslateit/version_fu/actions/workflows/ci.yml/badge.svg)](https://github.com/webtranslateit/version_fu/actions/workflows/ci.yml)
4
+
5
+ version_fu is a ActiveRecord versioning plugin that that is based on the dirty attribute checking introduced in Rails 2.1.
6
+
7
+ ## Installation
8
+
9
+ Add below to your Gemfile
10
+
11
+ `gem 'version_fu'`
12
+
13
+ ## Usage
14
+
15
+ Let's say I have a pages table:
16
+
17
+ ```ruby
18
+ class Page < ActiveRecord::Base
19
+ # attributes: id, type, title, body, created_at, updated_at, creator_id, author_id
20
+ end
21
+ ```
22
+
23
+ I want to track any changes made. First step will be to make a new page_versions table:
24
+
25
+ ```ruby
26
+ class CreatePageVersions < ActiveRecord::Migration
27
+ def self.up
28
+ create_table :page_versions do |t|
29
+ t.integer :page_id, :version, :author_id
30
+ t.string :title
31
+ t.text :body
32
+ t.timestamps
33
+ end
34
+ end
35
+
36
+ def self.down
37
+ drop_table :page_versions
38
+ end
39
+ end
40
+ ```
41
+
42
+ In this case, the author_id column represents the last person to edit the page. We want to track this attribute with every version. However, the creator_id is the person who created the page. The will never change, so it's not part of the versioned table.
43
+
44
+ Don't forget to add a version column to your pages table. Have it default to 1 just to be safe (although the plugin should account for this):
45
+
46
+ ```ruby
47
+ class AddVersionToPages < ActiveRecord::Migration
48
+ def self.up
49
+ add_column :pages, :version, :integer, :default=>1
50
+ end
51
+ def self.down
52
+ remove_column :pages, :version
53
+ end
54
+ end
55
+ ```
56
+
57
+ Of course if you're adding this plugin to a table with existing data, you'll probably want to instantiate some initial versions to start with.
58
+
59
+ Alright, so now that the database tables are in place, we can fire up version_fu. It's quite simple:
60
+
61
+ ```
62
+ class Page < ActiveRecord::Base
63
+ version_fu
64
+ end
65
+ ```
66
+
67
+ That's it.
68
+
69
+
70
+ ## Configuration
71
+
72
+ You can pass a few configuration options if need be. If you stick with the defaults above, you can skip all this.
73
+
74
+ ```ruby
75
+ class Page < ActiveRecord::Base
76
+ version_fu :class_name=>'Version', :foreign_key=>'page_id', :table_name=>'page_versions', :version_column=>'version'
77
+ end
78
+ ```
79
+
80
+ * :class_name - The name of the versioned class. It will be a submodule of the versioning class - e.g. Page::Version
81
+
82
+ * :foreign_key - The column in the versioned table associated with the versioning class
83
+
84
+ * :table_name - The name of the versioned table
85
+
86
+ * :version_column - The name of the version column
87
+
88
+
89
+ ## Extensions
90
+
91
+ Now that you've got some versions, it would be nice to use ActiveRecord associations on it. For example, Page.first.versions.latest.author wouldn't currently work because the Page::Version class doesn't know about the author method. The version_fu call does all you to pass a block which is executed by the versioned class. There is just one gotcha for associations:
92
+
93
+ ```ruby
94
+ class Page < ActiveRecord::Base
95
+ version_fu do
96
+ belongs_to :author, :class_name=>'::Author'
97
+ end
98
+ end
99
+ ```
100
+
101
+ Don't forget the class name, or you'll get a warning
102
+
103
+ ## When to Version
104
+
105
+ By default a new version will be saved whenever a versioned column is changed. However, you can control this at a more fine grained level. Just override the create_new_version? method. For example, let's say you only want to save a new version if both the page title and body changed. Taking advantage of the dirty attribute methods, you could do something like this:
106
+
107
+ ```ruby
108
+ class Page < ActiveRecord::Base
109
+ version_fu do
110
+ belongs_to :author, :class_name=>'::Author'
111
+ end
112
+ def create_new_version?
113
+ title_changed? && body_changed?
114
+ end
115
+ end
116
+ ```
117
+
118
+ ## Author
119
+
120
+ * version_fu was created by Jordan McKible http://jordan.mckible.com
121
+
122
+ * Available on GitHub at http://github.com/jmckible/version_fu
123
+
124
+ * Available on RubyGems.org at http://rubygems.org/gems/version_fu
125
+
126
+ * acts_as_versioned by Rick Olson http://github.com/technoweenie/acts_as_versioned/tree/master
data/Rakefile ADDED
@@ -0,0 +1,25 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rdoc/task'
4
+ require 'rubygems'
5
+ require 'bundler/gem_tasks'
6
+ require 'rspec/core/rake_task'
7
+ require 'rubocop/rake_task'
8
+
9
+ task default: %i[spec rubocop]
10
+ RSpec::Core::RakeTask.new
11
+
12
+ desc 'Run RuboCop checks'
13
+ RuboCop::RakeTask.new
14
+
15
+ desc 'Default: run unit tests.'
16
+ task default: :test
17
+
18
+ desc 'Test the version_fu plugin.'
19
+ Rake::TestTask.new(:test) do |t|
20
+ t.libs << 'lib'
21
+ t.libs << 'test'
22
+ t.libs << 'test/models'
23
+ t.pattern = 'test/**/*_test.rb'
24
+ t.verbose = true
25
+ end
data/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'version_fu'
2
+ ActiveRecord::Base.class_eval { include VersionFu }
@@ -0,0 +1,3 @@
1
+ module Version_fu
2
+ VERSION = '1.1.0'.freeze
3
+ end
@@ -0,0 +1,112 @@
1
+ module VersionFu
2
+ def self.included(base)
3
+ base.extend ClassMethods
4
+ end
5
+
6
+ module ClassMethods
7
+ def version_fu(options = {}, &block)
8
+ return if included_modules.include? VersionFu::InstanceMethods
9
+
10
+ __send__ :include, VersionFu::InstanceMethods
11
+
12
+ cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name,
13
+ :version_column, :versioned_columns
14
+
15
+ self.versioned_class_name = options[:class_name] || 'Version'
16
+ self.versioned_foreign_key = options[:foreign_key] || to_s.foreign_key
17
+ self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_versions#{table_name_suffix}"
18
+ self.version_column = options[:version_column] || 'version'
19
+
20
+ # Setup versions association
21
+ class_eval do
22
+ has_many :versions, class_name: "#{self}::#{versioned_class_name}",
23
+ foreign_key: versioned_foreign_key,
24
+ dependent: :destroy do
25
+ def latest
26
+ order(version: :desc).first
27
+ end
28
+ end
29
+
30
+ before_save :check_for_new_version
31
+ end
32
+
33
+ # Versioned Model
34
+ const_set(versioned_class_name, Class.new(ActiveRecord::Base)).class_eval do
35
+ # find first version before the given version
36
+ def self.before(version)
37
+ where("#{original_class.versioned_foreign_key} = ? and version < ?",
38
+ version.send(original_class.versioned_foreign_key), version.version)
39
+ .order(version: :desc).first
40
+ end
41
+
42
+ # find first version after the given version.
43
+ def self.after(version)
44
+ where("#{original_class.versioned_foreign_key} = ? and version > ?",
45
+ version.send(original_class.versioned_foreign_key), version.version)
46
+ .order(version: :asc).first
47
+ end
48
+
49
+ def previous
50
+ self.class.before(self)
51
+ end
52
+
53
+ def next
54
+ self.class.after(self)
55
+ end
56
+ end
57
+
58
+ # Housekeeping on versioned class
59
+ versioned_class.cattr_accessor :original_class
60
+ versioned_class.original_class = self
61
+ versioned_class.table_name = versioned_table_name
62
+
63
+ # Version parent association
64
+ versioned_class.belongs_to to_s.demodulize.underscore.to_sym,
65
+ class_name: "::#{self}",
66
+ foreign_key: versioned_foreign_key
67
+
68
+ # Block extension
69
+ versioned_class.class_eval(&block) if block_given?
70
+
71
+ if versioned_class.table_exists?
72
+ # Finally setup which columns to version
73
+ self.versioned_columns = versioned_class.new.attributes.keys -
74
+ [versioned_class.primary_key, versioned_foreign_key, version_column, 'created_at',
75
+ 'updated_at']
76
+ else
77
+ ActiveRecord::Base.logger.warn 'Version Table not found'
78
+ end
79
+ end
80
+
81
+ def versioned_class
82
+ const_get versioned_class_name
83
+ end
84
+ end
85
+
86
+ module InstanceMethods
87
+ def find_version(number)
88
+ versions.find_by_version(number)
89
+ end
90
+
91
+ def check_for_new_version
92
+ instantiate_revision if create_new_version?
93
+ true # Never halt save
94
+ end
95
+
96
+ # This the method to override if you want to have more control over when to version
97
+ def create_new_version?
98
+ # Any versioned column changed?
99
+ self.class.versioned_columns.detect { |a| __send__ "#{a}_changed?" }
100
+ end
101
+
102
+ def instantiate_revision
103
+ new_version = versions.build
104
+ versioned_columns.each do |attribute|
105
+ new_version.__send__ "#{attribute}=", __send__(attribute)
106
+ end
107
+ version_number = new_record? ? 1 : version + 1
108
+ new_version.version = version_number
109
+ self.version = version_number
110
+ end
111
+ end
112
+ end
data/lib/version_fu.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'active_record'
2
+ require 'version_fu/version_fu'
3
+ ActiveRecord::Base.class_eval { include VersionFu }
metadata ADDED
@@ -0,0 +1,238 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: webtranslateit-version_fu
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Jordan McKible
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-04-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '4.0'
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5.2'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: '4.0'
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5.2'
33
+ - !ruby/object:Gem::Dependency
34
+ name: rails-observers
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 0.1.2
40
+ type: :runtime
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - "~>"
45
+ - !ruby/object:Gem::Version
46
+ version: 0.1.2
47
+ - !ruby/object:Gem::Dependency
48
+ name: factory_girl
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ - !ruby/object:Gem::Dependency
62
+ name: factory_girl_rails
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - ">="
73
+ - !ruby/object:Gem::Version
74
+ version: '0'
75
+ - !ruby/object:Gem::Dependency
76
+ name: guard-rspec
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: guard-rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: mocha
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rails
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '4.0'
124
+ - - "<"
125
+ - !ruby/object:Gem::Version
126
+ version: '5.2'
127
+ type: :development
128
+ prerelease: false
129
+ version_requirements: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '4.0'
134
+ - - "<"
135
+ - !ruby/object:Gem::Version
136
+ version: '5.2'
137
+ - !ruby/object:Gem::Dependency
138
+ name: rspec
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - ">="
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ - !ruby/object:Gem::Dependency
152
+ name: rspec-rails
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '3.5'
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '3.5'
165
+ - !ruby/object:Gem::Dependency
166
+ name: rubocop
167
+ requirement: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ">="
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ type: :development
173
+ prerelease: false
174
+ version_requirements: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ">="
177
+ - !ruby/object:Gem::Version
178
+ version: '0'
179
+ - !ruby/object:Gem::Dependency
180
+ name: sqlite3
181
+ requirement: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ">="
184
+ - !ruby/object:Gem::Version
185
+ version: '0'
186
+ type: :development
187
+ prerelease: false
188
+ version_requirements: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ description: version_fu helps version your ActiveRecord models. It is based on Rick
194
+ Olson's acts_as_versioned and is compatible with Rails 3.
195
+ email: ''
196
+ executables: []
197
+ extensions: []
198
+ extra_rdoc_files: []
199
+ files:
200
+ - MIT-LICENSE
201
+ - README.md
202
+ - Rakefile
203
+ - init.rb
204
+ - lib/version_fu.rb
205
+ - lib/version_fu/version.rb
206
+ - lib/version_fu/version_fu.rb
207
+ homepage:
208
+ licenses:
209
+ - MIT
210
+ metadata:
211
+ rubygems_mfa_required: 'true'
212
+ homepage: https://github.com/webtranslateit/version_fu
213
+ changelog_uri: https://github.com/webtranslateit/webtranslateit/blob/master/history.md
214
+ documentation_uri: https://github.com/webtranslateit/webtranslateit#readme
215
+ homepage_uri: https://webtranslateit.com
216
+ source_code_uri: https://github.com/webtranslateit/webtranslateit
217
+ wiki_uri: https://github.com/webtranslateit/webtranslateit/wiki
218
+ post_install_message:
219
+ rdoc_options:
220
+ - "--charset=UTF-8"
221
+ require_paths:
222
+ - lib
223
+ required_ruby_version: !ruby/object:Gem::Requirement
224
+ requirements:
225
+ - - ">="
226
+ - !ruby/object:Gem::Version
227
+ version: '0'
228
+ required_rubygems_version: !ruby/object:Gem::Requirement
229
+ requirements:
230
+ - - ">="
231
+ - !ruby/object:Gem::Version
232
+ version: '0'
233
+ requirements: []
234
+ rubygems_version: 3.1.6
235
+ signing_key:
236
+ specification_version: 4
237
+ summary: Gemified version of the version_fu plugin.
238
+ test_files: []