acts_as_versioner 1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -0
- data/README.md +58 -0
- data/Rakefile +10 -0
- data/VERSION +1 -0
- data/acts_as_versioner.gemspec +33 -0
- data/lib/acts_as_versioner/acts_as_versioner.rb +325 -0
- data/lib/acts_as_versioner/userstamp.rb +22 -0
- data/lib/acts_as_versioner.rb +20 -0
- metadata +108 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4d2358c69672d8feac037526ab9513951a5ae197
|
4
|
+
data.tar.gz: 848639453794e3025c584b834ebf073aca5f88c2
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: ec883fcad954d7ac02bb1b1a223386f980a425a28f2cb20a0241d996337b30465771c2b58fa5deb9c475781e65c2626a0b3493bcea3e0f044caf3c1eb16e89bf
|
7
|
+
data.tar.gz: 4cb7cc81cbbab950970caac6657e1dcf455b7b6be99e240ab90843d751abd271ebe54281a29d85c70927f5b4188873717faf20db1eff737379cd3a5065017fcc
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
ActsAsVersioner
|
2
|
+
=================
|
3
|
+
|
4
|
+
This gem is versioning changes of a database table into a underlying table with the same name rules but a "_versions" appendix. Just add
|
5
|
+
"acts_as_versioner" in class definition of a model you want versioning to happen. Then create a new table by using the method "create_versioned_table". If you change tables, make sure the changes take also place in the versioned table, you can use the method "adapt_versioned_table" for that (User.adapt_versioned_table).
|
6
|
+
|
7
|
+
table name: "name of the original table in singluar demodulized form" + "_versions"
|
8
|
+
table format:
|
9
|
+
- Primary Key: id integer not null auto_increment
|
10
|
+
- "action":
|
11
|
+
* 0 stands for created
|
12
|
+
* 1 stands for updated
|
13
|
+
* 2 stands for destroyed
|
14
|
+
- From here there are the same columns like in the original table. It must be pointed out that the column "id" of the original table is in the format of the original table in singluar demodulized form" + "_id"
|
15
|
+
- Timestamps are automatically added
|
16
|
+
- Editor id's are added through Userstamp
|
17
|
+
|
18
|
+
This gem expands a model class, marked with keyword "acts_as_versioner", with following methods:
|
19
|
+
|
20
|
+
def get_current_version
|
21
|
+
- Returns the current version, here e.g. Entry (table 'entries' and 'entry_versions')
|
22
|
+
-> #<Entry::EntryVersion id: 5, entry_id: 2, action: 1, ..., created_by: [User.id], updated_by: [User.id], created_at: [DateTime], updated_at: [DateTime]>
|
23
|
+
|
24
|
+
def get_versions
|
25
|
+
- Returns all versions of a model, here e.g. Entry (table 'entries' and 'entry_versions')
|
26
|
+
-> [#<Entry::EntryVersion id: 1, entry_id: 1, action: 0,...>, #<Entry::EntryVersion id: 2, entry_id: 1, action: 1, ...>]
|
27
|
+
|
28
|
+
Userstamp
|
29
|
+
=========
|
30
|
+
|
31
|
+
This module expects a current_user to be present (devise, authlogic etc). In order to be able to access to current_user in models and modules, necessary methods in application_controller and user.rb have to be available. If there is no current_user Userstamp will set 0 as version editor...
|
32
|
+
|
33
|
+
app/controllers/application_controller
|
34
|
+
---
|
35
|
+
|
36
|
+
around_action :setcurrentuser, :except => [:sign_in]
|
37
|
+
|
38
|
+
....
|
39
|
+
|
40
|
+
protected
|
41
|
+
|
42
|
+
def setcurrentuser
|
43
|
+
User.current_user = current_user.nil? ? nil : User.find(current_user.id)
|
44
|
+
yield
|
45
|
+
ensure
|
46
|
+
User.current_user = nil
|
47
|
+
end
|
48
|
+
|
49
|
+
app/models/user.rb
|
50
|
+
---
|
51
|
+
|
52
|
+
def self.current_user
|
53
|
+
Thread.current[:current_user]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.current_user=(usr)
|
57
|
+
Thread.current[:current_user] = usr
|
58
|
+
end
|
data/Rakefile
ADDED
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
1.0
|
@@ -0,0 +1,33 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "acts_as_versioner"
|
3
|
+
s.version = "1.0"
|
4
|
+
|
5
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
6
|
+
s.authors = ["Markus Hediger"]
|
7
|
+
s.date = "2018-01-01"
|
8
|
+
s.description = "Versioning of ar tables"
|
9
|
+
s.email = "m.hed@gmx.ch"
|
10
|
+
s.extra_rdoc_files = [
|
11
|
+
"README.md"
|
12
|
+
]
|
13
|
+
s.files = [
|
14
|
+
"Gemfile",
|
15
|
+
"README.md",
|
16
|
+
"Rakefile",
|
17
|
+
"VERSION",
|
18
|
+
"lib/acts_as_versioner/acts_as_versioner.rb",
|
19
|
+
"lib/acts_as_versioner/userstamp.rb",
|
20
|
+
"lib/acts_as_versioner.rb",
|
21
|
+
"acts_as_versioner.gemspec"
|
22
|
+
]
|
23
|
+
s.homepage = "http://github.com/kusihed/acts_as_versioner"
|
24
|
+
s.licenses = ["MIT"]
|
25
|
+
s.require_paths = ["lib"]
|
26
|
+
s.summary = "Versioning of ar tables"
|
27
|
+
|
28
|
+
s.add_development_dependency "rails", "~> 5.0"
|
29
|
+
s.add_development_dependency "bundler", '~> 0'
|
30
|
+
s.add_development_dependency "rake", '~> 0'
|
31
|
+
s.add_development_dependency "sqlite3", '~> 0'
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,325 @@
|
|
1
|
+
# This module serves to versioning of data sets. If a new data set is created, updated or destroyed, the old data set gets saved into a second table.
|
2
|
+
# The second table has the same name like the original table but is expanded with "Version".
|
3
|
+
# => E.g. User -> UserVersions
|
4
|
+
|
5
|
+
# ActsAsVersioner
|
6
|
+
|
7
|
+
module ActiveRecord
|
8
|
+
module Acts
|
9
|
+
module Versioner
|
10
|
+
|
11
|
+
def self.included(mod)
|
12
|
+
mod.extend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def acts_as_versioner(options = {}, &extension)
|
17
|
+
include ActiveRecord::Acts::Versioner::InstanceMethods
|
18
|
+
|
19
|
+
# don't allow multiple calls
|
20
|
+
return if self.included_modules.include?(ActiveRecord::Acts::Versioner::ActMethods)
|
21
|
+
|
22
|
+
send :include, ActiveRecord::Acts::Versioner::ActMethods
|
23
|
+
|
24
|
+
cattr_accessor :versioned_class_name, :versioned_foreign_key, :versioned_table_name
|
25
|
+
|
26
|
+
send :attr_accessor
|
27
|
+
|
28
|
+
self.versioned_class_name = options[:class_name] || "#{base_class}Version"
|
29
|
+
self.versioned_table_name = options[:table_name] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_class_name]}#{table_name_suffix}"
|
30
|
+
self.versioned_foreign_key = options[:versioned_foreign_key] || "#{table_name_prefix}#{base_class.name.demodulize.underscore}_id" # quick 'n' dirty fix
|
31
|
+
|
32
|
+
if block_given?
|
33
|
+
extension_module_name = "#{versioned_class_name}Extension"
|
34
|
+
silence_warnings do
|
35
|
+
self.const_set(extension_module_name, Module.new(&extension))
|
36
|
+
end
|
37
|
+
options[:extend] = self.const_get(extension_module_name)
|
38
|
+
end
|
39
|
+
|
40
|
+
class_eval do
|
41
|
+
include options[:extend] if options[:extend].is_a?(Module)
|
42
|
+
|
43
|
+
before_save :b_s
|
44
|
+
before_destroy :b_d
|
45
|
+
after_save :a_s
|
46
|
+
after_destroy :a_d
|
47
|
+
end
|
48
|
+
|
49
|
+
# create the dynamic versioned model
|
50
|
+
const_set(versioned_class_name, Class.new(ApplicationRecord)).class_eval do
|
51
|
+
def self.reloadable? ; false ; end
|
52
|
+
end
|
53
|
+
|
54
|
+
versioned_class.table_name = "#{versioned_table_name}"
|
55
|
+
versioned_class.belongs_to self.to_s.demodulize.underscore.to_sym, :class_name => "#{self.to_s}::#{versioned_class_name}", :foreign_key => versioned_foreign_key
|
56
|
+
versioned_class.send :include, options[:extend] if options[:extend].is_a?(Module)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
module InstanceMethods
|
61
|
+
attr_accessor :acts_as_versioner_model
|
62
|
+
attr_accessor :acts_as_versioner_mode
|
63
|
+
|
64
|
+
# Returns the current version.
|
65
|
+
def get_current_version
|
66
|
+
instance_eval(self.versioned_class_name).where([self.versioned_foreign_key + ' = ?', self.id]).order("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} desc, id desc").first
|
67
|
+
end
|
68
|
+
|
69
|
+
# Returns all versions of a model.
|
70
|
+
def get_versions
|
71
|
+
instance_eval(self.versioned_class_name).where([self.versioned_foreign_key + ' = ?', self.id]).order("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} asc, id asc").all
|
72
|
+
end
|
73
|
+
|
74
|
+
# This methods returns all versions of associated tables (table that belong to the existing model).
|
75
|
+
def get_versions_children
|
76
|
+
associations = Hash.new # result hash
|
77
|
+
stack = Array.new # Stack of the same algorithm.
|
78
|
+
|
79
|
+
# Initiate algorithm with the used model
|
80
|
+
versions = instance_eval(self.versioned_class_name).where([self.versioned_foreign_key + ' = ?', self.id]).order("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} asc, #{ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at]} asc").all
|
81
|
+
associations[self.versioned_class_name] = versions # Caching itself in the result hash
|
82
|
+
stack.push self.class => versions # Setting itself onto the stack
|
83
|
+
|
84
|
+
# Main loop of the algorith
|
85
|
+
while class_struct = stack.pop
|
86
|
+
class_name = nil
|
87
|
+
data_set = nil
|
88
|
+
|
89
|
+
class_struct.each do |key_class_name, value_data_set|
|
90
|
+
class_name = key_class_name
|
91
|
+
data_set = value_data_set
|
92
|
+
end
|
93
|
+
|
94
|
+
# Read all assocations
|
95
|
+
reflection_assoc = Array.new
|
96
|
+
reflection_assoc.concat(class_name.reflect_on_all_associations(:has_one))
|
97
|
+
reflection_assoc.concat(class_name.reflect_on_all_associations(:has_many))
|
98
|
+
reflection_assoc.compact!
|
99
|
+
|
100
|
+
# Iterate through all associations
|
101
|
+
reflection_assoc.each do |association|
|
102
|
+
association_klass = association.klass
|
103
|
+
# Is there a versioning table? If yes, go back to the beginning of the iteration..
|
104
|
+
if association_klass.to_s.include?("version") then next end
|
105
|
+
child_associations_has_one = association_klass.reflect_on_all_associations(:has_one)
|
106
|
+
child_associations_has_many = association_klass.reflect_on_all_associations(:has_many)
|
107
|
+
|
108
|
+
# Does the associated table have further associated tables and did they already be iterated through?
|
109
|
+
if (child_associations_has_one.empty? || child_associations_has_many.empty?) && associations[association_klass.versioned_class_name] != nil then next end
|
110
|
+
|
111
|
+
new_data_set = Array.new
|
112
|
+
# Check if the table has been visited already. If yes, complete the data sets -> Does only happen if we have a table without associations.
|
113
|
+
if associations[association_klass.versioned_class_name] != nil then new_data_set = associations[association_klass.versioned_class_name] end
|
114
|
+
|
115
|
+
foreign_ids = []
|
116
|
+
data_set.each { |data|
|
117
|
+
foreign_ids << instance_eval("data." + class_name.to_s.tableize.singularize.downcase + "_id.to_s")
|
118
|
+
}
|
119
|
+
|
120
|
+
unless foreign_ids.blank?
|
121
|
+
tmp_new_data_set = association_klass.versioned_class.where(["#{class_name.to_s.tableize.singularize.downcase}_id IN (?)", foreign_ids]).order("#{ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at]} asc, #{ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at]} asc").all
|
122
|
+
unless tmp_new_data_set.blank? then new_data_set.concat(tmp_new_data_set) end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Cache the found data sets into the result hash
|
126
|
+
associations[association_klass.versioned_class_name] = new_data_set
|
127
|
+
# Additionally found data sets get saved on the stack for the next iteration
|
128
|
+
stack.push association_klass => new_data_set
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# Remove all double entries
|
133
|
+
associations.each do |class_name_to_s, versionArray|
|
134
|
+
versionArray.uniq!
|
135
|
+
end
|
136
|
+
|
137
|
+
return associations
|
138
|
+
end
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
# This method overrides the default method "before_save" of the ActiveRecord class.
|
143
|
+
# It is invoked before the actual saving takes place and serves to preparing the versioning.
|
144
|
+
def b_s
|
145
|
+
prepare_versioning
|
146
|
+
end
|
147
|
+
|
148
|
+
# This method overrides the default method "before_destroy" of the ActiveRecord class.
|
149
|
+
# It is invoked before the actual destroying takes place and serves to preparing the versioning.
|
150
|
+
def b_d
|
151
|
+
prepare_versioning 2
|
152
|
+
end
|
153
|
+
|
154
|
+
# This method overrides the default method "after_save" of the ActiveRecord class.
|
155
|
+
# It is invoked after the actual saving has token place and serves to execute the versioning.
|
156
|
+
def a_s
|
157
|
+
do_versioning
|
158
|
+
end
|
159
|
+
|
160
|
+
# This method overrides the default method "after_destroy" of the ActiveRecord class.
|
161
|
+
# It is invoked after the actual destroying has token place and serves to execute the versioning.
|
162
|
+
def a_d
|
163
|
+
do_versioning
|
164
|
+
end
|
165
|
+
|
166
|
+
# This method is preparing the versioning. It copies the current object and saves it into a variable.
|
167
|
+
# For the number it is assumed to be between 0 and 2 depending on the mode (0 = insert, 1 = update, 2 = delete).
|
168
|
+
def prepare_versioning(mode = 0)
|
169
|
+
@acts_as_versioner_mode = mode # mode : 0 = insert, 1 = update, 2 = delete
|
170
|
+
@acts_as_versioner_model = self.dup
|
171
|
+
@acts_as_versioner_model.updated_at = Time.now
|
172
|
+
|
173
|
+
if mode == 0 && self.id != nil then @acts_as_versioner_mode = 1 end
|
174
|
+
end
|
175
|
+
|
176
|
+
# In this method the versioning is happening. It expects a copy of the current object in the variable @acts_as_versioner_mode.
|
177
|
+
# It will be invoked after the method "prepare_versioning"
|
178
|
+
def do_versioning
|
179
|
+
attributes = Hash.new
|
180
|
+
# Save variables and the values in a hash
|
181
|
+
@acts_as_versioner_model.attributes.each do |attribute, value|
|
182
|
+
attributes[attribute] = value unless attribute == "id" # ID has to be excluded because MassAssignment warning...
|
183
|
+
end
|
184
|
+
|
185
|
+
@acts_as_versioner_model = nil
|
186
|
+
|
187
|
+
attributes[self.versioned_foreign_key] = self.id
|
188
|
+
attributes[:action] = @acts_as_versioner_mode
|
189
|
+
|
190
|
+
modelversion = instance_eval(self.versioned_class_name).new(attributes)
|
191
|
+
modelversion.save(:validate => false)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
module ActMethods
|
196
|
+
def self.included(base) # :nodoc:
|
197
|
+
base.extend ClassMethods
|
198
|
+
end
|
199
|
+
|
200
|
+
private
|
201
|
+
|
202
|
+
def empty_callback() end #:nodoc:
|
203
|
+
|
204
|
+
module ClassMethods
|
205
|
+
|
206
|
+
# Returns an array of columns that are versioned. See non_versioned_columns
|
207
|
+
def versioned_columns
|
208
|
+
self.columns.select { |c| c.name }
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns an instance of the dynamic versioned model
|
212
|
+
def versioned_class
|
213
|
+
const_get versioned_class_name
|
214
|
+
end
|
215
|
+
|
216
|
+
# Rake migration task to create the versioned table
|
217
|
+
def create_versioned_table(create_table_options = {})
|
218
|
+
versioned_table_name = self.to_s.underscore + ActiveRecord::Acts::Versioner::configurator[:default_versioned_class_name]
|
219
|
+
puts table_name
|
220
|
+
# create version column in main table if it does not exist
|
221
|
+
add_column_to_table(table_name, ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_at], :datetime)
|
222
|
+
add_column_to_table(table_name, ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_at], :datetime)
|
223
|
+
add_column_to_table(table_name, ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_by], :integer)
|
224
|
+
add_column_to_table(table_name, ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_by], :integer)
|
225
|
+
|
226
|
+
|
227
|
+
# create versions table
|
228
|
+
self.connection.create_table(versioned_table_name, create_table_options) do |t|
|
229
|
+
t.column versioned_foreign_key, :integer
|
230
|
+
t.column :action, :integer, :null => false, :default => 0
|
231
|
+
end
|
232
|
+
|
233
|
+
# clone the original table in order to create the versions table
|
234
|
+
puts versioned_table_name
|
235
|
+
not_versioned = %w{id}
|
236
|
+
self.versioned_columns.each do |col|
|
237
|
+
unless not_versioned.include?(col.name)
|
238
|
+
self.connection.add_column versioned_table_name, col.name, col.type,
|
239
|
+
:limit => col.limit,
|
240
|
+
:default => col.default
|
241
|
+
end
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
def add_column_to_table(table, column, type)
|
246
|
+
tabelle = self.connection.execute("show columns from #{table} like '#{column}'")
|
247
|
+
|
248
|
+
do_add = true
|
249
|
+
for res in tabelle
|
250
|
+
do_add = false if column.to_s == res.first.to_s
|
251
|
+
end
|
252
|
+
if do_add
|
253
|
+
self.connection.add_column table, column, type
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
# Rake migration task to drop the versioned table
|
258
|
+
def drop_versioned_table
|
259
|
+
self.connection.drop_table versioned_table_name
|
260
|
+
end
|
261
|
+
|
262
|
+
# If a column is added call this method to adapt the versioned table
|
263
|
+
def adapt_versioned_table
|
264
|
+
not_versioned = ["id", "action", versioned_foreign_key.to_s]
|
265
|
+
versioned_columns = []
|
266
|
+
self.connection.execute("show columns from #{versioned_table_name}").each { |col|
|
267
|
+
versioned_columns << [col[0], col[1]] unless not_versioned.include?(col[0])
|
268
|
+
}
|
269
|
+
|
270
|
+
missing = []
|
271
|
+
changed = []
|
272
|
+
|
273
|
+
reset_columns = []
|
274
|
+
self.connection.execute("show columns from #{table_name}").each { |col|
|
275
|
+
reset_columns << [col[0], col[1]] unless not_versioned.include?(col[0])
|
276
|
+
}
|
277
|
+
|
278
|
+
reset_columns.each do |rc|
|
279
|
+
found = versioned_columns.detect{ |wc| wc.first == rc.first }
|
280
|
+
unless found.blank?
|
281
|
+
changed << rc if rc.last.to_s != found.last.to_s
|
282
|
+
versioned_columns.delete_if { |k| k.first == rc.first }
|
283
|
+
else
|
284
|
+
missing << rc
|
285
|
+
end
|
286
|
+
end
|
287
|
+
|
288
|
+
# Add new column
|
289
|
+
missing.each do |m|
|
290
|
+
self.connection.add_column versioned_table_name, m.first, m.last
|
291
|
+
end
|
292
|
+
|
293
|
+
# Change column
|
294
|
+
changed.each do |c|
|
295
|
+
self.connection.change_column versioned_table_name, c.first, c.last
|
296
|
+
end
|
297
|
+
|
298
|
+
# Remove column
|
299
|
+
versioned_columns.each do |vc|
|
300
|
+
self.connection.remove_column versioned_table_name, vc.first
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
# You can resurrect a destroyed entry by its versioned foreign key
|
305
|
+
def resurrect(id)
|
306
|
+
destroyed_version = self.versioned_class.where(self.versioned_foreign_key => id).last
|
307
|
+
if destroyed_version && destroyed_version.action == 2
|
308
|
+
model = self.new
|
309
|
+
self.columns.map{|c| c.name}.each do |c|
|
310
|
+
model[c] = destroyed_version[c] unless c == "id"
|
311
|
+
model[c] = id if c == "id"
|
312
|
+
model[c] = Time.now if c == "updated_at"
|
313
|
+
end
|
314
|
+
model.save
|
315
|
+
return model if model.errors.blank?
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Userstamp
|
2
|
+
extend ActiveSupport::Concern
|
3
|
+
|
4
|
+
included do
|
5
|
+
# It's important to use before_save here because of the hierarchy in callbacks (see acts_as_versioner)
|
6
|
+
before_save :set_stamps
|
7
|
+
end
|
8
|
+
|
9
|
+
def set_stamps
|
10
|
+
if defined?(User)
|
11
|
+
stamper = 0 # System
|
12
|
+
stamper = User.current_user.id if User.current_user
|
13
|
+
if self.id.blank?
|
14
|
+
self[ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_by]] = stamper if self.has_attribute? ActiveRecord::Acts::Versioner::configurator[:default_versioned_created_by]
|
15
|
+
self[ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_by]] = stamper if self.has_attribute? ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_by]
|
16
|
+
else
|
17
|
+
self[ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_by]] = stamper if self.has_attribute? ActiveRecord::Acts::Versioner::configurator[:default_versioned_updated_by]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/acts_as_versioner/acts_as_versioner.rb'
|
2
|
+
require File.dirname(__FILE__) + '/acts_as_versioner/userstamp.rb'
|
3
|
+
module ActiveRecord::Acts::Versioner
|
4
|
+
@@configurator = {
|
5
|
+
:default_versioned_class_name => '_versions',
|
6
|
+
:default_versioned_created_at => 'created_at',
|
7
|
+
:default_versioned_updated_at => 'updated_at',
|
8
|
+
:default_versioned_created_by => 'created_by',
|
9
|
+
:default_versioned_updated_by => 'updated_by'
|
10
|
+
}
|
11
|
+
mattr_reader :configurator
|
12
|
+
end
|
13
|
+
|
14
|
+
class ActiveRecord::Base
|
15
|
+
include Userstamp
|
16
|
+
end
|
17
|
+
|
18
|
+
ActiveRecord::Base.class_eval do
|
19
|
+
include ActiveRecord::Acts::Versioner
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: acts_as_versioner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '1.0'
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Markus Hediger
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-01-01 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: '5.0'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: sqlite3
|
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
|
+
description: Versioning of ar tables
|
70
|
+
email: m.hed@gmx.ch
|
71
|
+
executables: []
|
72
|
+
extensions: []
|
73
|
+
extra_rdoc_files:
|
74
|
+
- README.md
|
75
|
+
files:
|
76
|
+
- Gemfile
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- VERSION
|
80
|
+
- acts_as_versioner.gemspec
|
81
|
+
- lib/acts_as_versioner.rb
|
82
|
+
- lib/acts_as_versioner/acts_as_versioner.rb
|
83
|
+
- lib/acts_as_versioner/userstamp.rb
|
84
|
+
homepage: http://github.com/kusihed/acts_as_versioner
|
85
|
+
licenses:
|
86
|
+
- MIT
|
87
|
+
metadata: {}
|
88
|
+
post_install_message:
|
89
|
+
rdoc_options: []
|
90
|
+
require_paths:
|
91
|
+
- lib
|
92
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
requirements: []
|
103
|
+
rubyforge_project:
|
104
|
+
rubygems_version: 2.6.13
|
105
|
+
signing_key:
|
106
|
+
specification_version: 4
|
107
|
+
summary: Versioning of ar tables
|
108
|
+
test_files: []
|