change_log 1.0.0 → 1.0.1
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/README.textile +33 -13
- data/change_log.gemspec +2 -3
- data/lib/change_log/version.rb +1 -1
- data/test/boot.rb +21 -0
- data/test/change_log_test.rb +39 -0
- data/test/database.yml +22 -0
- data/test/fixtures/change_logs.yml +24 -0
- data/test/fixtures/schema.rb +24 -0
- data/test/fixtures/test.rb +3 -0
- data/test/lib/activerecord_test_case.rb +43 -0
- data/test/lib/activerecord_test_connector.rb +76 -0
- data/test/lib/load_fixtures.rb +8 -0
- metadata +27 -23
data/README.textile
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
h1. Change Log
|
2
2
|
|
3
|
-
A gem to keep all changes about the
|
4
|
-
It automatically saves who made the changes at what time and what has been changed
|
5
|
-
You can choose the
|
6
|
-
|
3
|
+
A gem to keep all changes about the data in database.
|
4
|
+
It automatically saves who made the changes at what time and what has been changed.
|
5
|
+
You can choose to skip the column which you do not want to keep change logs.
|
6
|
+
For example: 'updated_at', 'created_at' and 'password' etc.
|
7
7
|
|
8
8
|
|
9
9
|
h2. Install Change Log Gem
|
@@ -28,14 +28,14 @@ Then:
|
|
28
28
|
You need to override that and replace it with support for Bundler.
|
29
29
|
Visit "Bundler Website":http://gembundler.com/rails23.html to find out how.
|
30
30
|
|
31
|
-
|
31
|
+
3. Create a table to keep all changes
|
32
32
|
|
33
|
-
Generate a migration file
|
33
|
+
Generate a migration file similar to this:
|
34
34
|
|
35
35
|
<pre><code>
|
36
36
|
class AddChangeLog < ActiveRecord::Migration
|
37
37
|
def self.up
|
38
|
-
create_table :change_logs do |t|
|
38
|
+
create_table :change_logs do |t| # feel free to choose another table name
|
39
39
|
t.integer :version, :null=>false # store version of each change
|
40
40
|
t.string :record_id,:limit=>30 # store the actual record id
|
41
41
|
t.string :table_name, :limit=>60 # store the table name
|
@@ -58,7 +58,7 @@ h2. Create a table to keep all changes
|
|
58
58
|
Then:
|
59
59
|
<pre><code>rake db:migrate</code></pre>
|
60
60
|
|
61
|
-
h2. Use Change Log
|
61
|
+
h2. Use Change Log Gem
|
62
62
|
|
63
63
|
1. *Add current_user Method in application_controller.rb*
|
64
64
|
|
@@ -70,7 +70,7 @@ end
|
|
70
70
|
</code></pre>
|
71
71
|
|
72
72
|
2. *ActiveRecord Models*
|
73
|
-
|
73
|
+
Enable change_log for Active Record Model,
|
74
74
|
just put following line in very beginning of model file.
|
75
75
|
<pre><code>
|
76
76
|
enable_change_log :ignore=>[:updated_at]
|
@@ -79,6 +79,27 @@ enable_change_log :ignore=>[:updated_at]
|
|
79
79
|
Put any columns you do not want to keep in the change log table in :ignore option.
|
80
80
|
eg. the password hash
|
81
81
|
|
82
|
+
Then the system should record every changes the user made to change_log table.
|
83
|
+
If you are making changes within Model file:
|
84
|
+
For Example:
|
85
|
+
<pre><code># this is a model file
|
86
|
+
def making_some_changes
|
87
|
+
user = User.find(:first)
|
88
|
+
user.email = 'peterz@ncs.co.nz'
|
89
|
+
user.save
|
90
|
+
end
|
91
|
+
</code></pre>
|
92
|
+
|
93
|
+
An attribute called 'whodidit' is automatically available.
|
94
|
+
So if you want to keep the changes in this scenario, do following:
|
95
|
+
<pre><code># this is a model file
|
96
|
+
def making_some_changes
|
97
|
+
user = User.find(:first)
|
98
|
+
user.email = 'peterz@ncs.co.nz'
|
99
|
+
user.whodidit = 'Peter'
|
100
|
+
user.save
|
101
|
+
end
|
102
|
+
</code></pre>
|
82
103
|
|
83
104
|
3. *About the ChangeLogs Model*
|
84
105
|
ChangeLogs model is core ActiveRecord model used by change_log gem.
|
@@ -105,9 +126,8 @@ ChangeLogs.find(:all,:conditions=>['table_name = ?', 'accounts'])</code></pre>
|
|
105
126
|
ChangeLogs.set_table_name('hr_maintenances')
|
106
127
|
</code></pre>
|
107
128
|
|
108
|
-
h2.
|
109
|
-
|
110
|
-
TODO
|
129
|
+
h2. Wish List
|
130
|
+
Please email me if you have any enquiry.
|
111
131
|
|
112
132
|
|
113
133
|
h3. Author
|
@@ -116,4 +136,4 @@ h3. Author
|
|
116
136
|
Peter Zhang at NCS New Zealand.
|
117
137
|
Email: peterz@ncs.co.nz
|
118
138
|
|
119
|
-
Copyright (c) 2011 Peter Zhang, released under the MIT license
|
139
|
+
Copyright (c) 2011 Peter Zhang and NCS LTD, released under the MIT license
|
data/change_log.gemspec
CHANGED
@@ -9,10 +9,9 @@ Gem::Specification.new do |s|
|
|
9
9
|
s.authors = ["Peter Zhang"]
|
10
10
|
s.email = ["peterz@ncs.co.nz"]
|
11
11
|
s.homepage = "http://www.ncs.co.nz"
|
12
|
-
s.summary = %q{Change log gem
|
13
|
-
s.description = %q{A gem for tracking who did what
|
12
|
+
s.summary = %q{Change log gem records every changes for the active record model}
|
13
|
+
s.description = %q{A gem for tracking who did what and when it happened -- keeps all the changes done by user into a maintenance log}
|
14
14
|
|
15
|
-
s.add_development_dependency "rspec"
|
16
15
|
s.rubyforge_project = "change_log"
|
17
16
|
|
18
17
|
s.files = `git ls-files`.split("\n")
|
data/lib/change_log/version.rb
CHANGED
data/test/boot.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
plugin_root = File.join(File.dirname(__FILE__), '..')
|
2
|
+
version = ENV['RAILS_VERSION']
|
3
|
+
version = nil if version and version == ""
|
4
|
+
|
5
|
+
# first look for a symlink to a copy of the framework
|
6
|
+
if !version and framework_root = ["#{plugin_root}/rails", "#{plugin_root}/../../rails"].find { |p| File.directory? p }
|
7
|
+
puts "found framework root: #{framework_root}"
|
8
|
+
# this allows for a plugin to be tested outside of an app and without Rails gems
|
9
|
+
$:.unshift "#{framework_root}/activesupport/lib", "#{framework_root}/activerecord/lib", "#{framework_root}/actionpack/lib"
|
10
|
+
else
|
11
|
+
# simply use installed gems if available
|
12
|
+
puts "using Rails#{version ? ' ' + version : nil} gems"
|
13
|
+
require 'rubygems'
|
14
|
+
|
15
|
+
if version
|
16
|
+
gem 'rails', version
|
17
|
+
else
|
18
|
+
gem 'actionpack', '< 3.0.0.a'
|
19
|
+
gem 'activerecord', '< 3.0.0.a'
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'lib/activerecord_test_case'
|
4
|
+
require 'action_controller'
|
5
|
+
require 'change_log'
|
6
|
+
|
7
|
+
class ChangeLogTest < ActiveRecordTestCase
|
8
|
+
fixtures :change_logs
|
9
|
+
|
10
|
+
# insert an new record
|
11
|
+
# then check the total number
|
12
|
+
def test_update_change_log_record_with
|
13
|
+
option = {:action=>'INSERT', :record_id=>3,:table_name=>'test', :user=>'test',:attribute_name=>'test',:new_value=>'50',:version=>1}
|
14
|
+
assert_equal true, ChangeLogs.update_change_log_record_with(option)
|
15
|
+
assert_equal 3, ChangeLogs.count()
|
16
|
+
end
|
17
|
+
|
18
|
+
# it should pick up the largest version number from fixture file
|
19
|
+
def test_get_version_number
|
20
|
+
assert_equal 3, ChangeLogs.get_version_number(1,'test')
|
21
|
+
end
|
22
|
+
|
23
|
+
# it will get the type of field from the table
|
24
|
+
def test_get_field_type
|
25
|
+
assert_equal 'integer', ChangeLogs.get_field_type('test','total')
|
26
|
+
end
|
27
|
+
|
28
|
+
# some logic test
|
29
|
+
def test_change_log_logic
|
30
|
+
# find a test, update the total
|
31
|
+
version_number = ChangeLogs.get_version_number(1,'test')
|
32
|
+
option = {:action=>'UPDATE', :record_id=>1,:table_name=>'test', :user=>'peterz',:attribute_name=>'test',:new_value=>'999',:old_value=>'100',:version=>version_number}
|
33
|
+
assert_equal true, ChangeLogs.update_change_log_record_with(option)
|
34
|
+
change_log = ChangeLogs.find(version_number)
|
35
|
+
assert_equal 'peterz',change_log.user
|
36
|
+
assert_equal '999', change_log.new_value
|
37
|
+
assert_equal '100', change_log.old_value
|
38
|
+
end
|
39
|
+
end
|
data/test/database.yml
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
sqlite3:
|
2
|
+
database: ":memory:"
|
3
|
+
adapter: sqlite3
|
4
|
+
timeout: 500
|
5
|
+
|
6
|
+
sqlite2:
|
7
|
+
database: ":memory:"
|
8
|
+
adapter: sqlite2
|
9
|
+
|
10
|
+
mysql:
|
11
|
+
adapter: mysql
|
12
|
+
username: root
|
13
|
+
password:
|
14
|
+
encoding: utf8
|
15
|
+
database: will_paginate_unittest
|
16
|
+
|
17
|
+
postgres:
|
18
|
+
adapter: postgresql
|
19
|
+
username: mislav
|
20
|
+
password:
|
21
|
+
database: will_paginate_unittest
|
22
|
+
min_messages: warning
|
@@ -0,0 +1,24 @@
|
|
1
|
+
log_1:
|
2
|
+
id: 1
|
3
|
+
version: 1
|
4
|
+
record_id: 1
|
5
|
+
table_name: test
|
6
|
+
field_type: int
|
7
|
+
action: 'INSERT'
|
8
|
+
attribute_name: total
|
9
|
+
user: tester
|
10
|
+
old_value: 10
|
11
|
+
new_value: 100
|
12
|
+
log_2:
|
13
|
+
id: 2
|
14
|
+
version: 2
|
15
|
+
record_id: 1
|
16
|
+
table_name: test
|
17
|
+
field_type: int
|
18
|
+
action: 'INSERT'
|
19
|
+
attribute_name: total
|
20
|
+
user: tester
|
21
|
+
old_value: 100
|
22
|
+
new_value: 1
|
23
|
+
|
24
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
ActiveRecord::Schema.define do
|
2
|
+
|
3
|
+
create_table "test" do |t|
|
4
|
+
t.column "total", :integer
|
5
|
+
t.column "created_at", :datetime
|
6
|
+
t.column "updated_at", :datetime
|
7
|
+
end
|
8
|
+
|
9
|
+
|
10
|
+
create_table "change_logs" do |t|
|
11
|
+
t.column "id", :integer, :null => false
|
12
|
+
t.column "version", :integer, :null => false
|
13
|
+
t.column "record_id", :integer
|
14
|
+
t.column "table_name", :string
|
15
|
+
t.column "field_type", :string
|
16
|
+
t.column "attribute_name", :string
|
17
|
+
t.column "action", :string
|
18
|
+
t.column "user", :string
|
19
|
+
t.column "old_value", :string
|
20
|
+
t.column "new_value", :string
|
21
|
+
t.timestamps
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'lib/activerecord_test_connector'
|
2
|
+
|
3
|
+
class ActiveRecordTestCase < Test::Unit::TestCase
|
4
|
+
if defined?(ActiveSupport::Testing::SetupAndTeardown)
|
5
|
+
include ActiveSupport::Testing::SetupAndTeardown
|
6
|
+
end
|
7
|
+
|
8
|
+
if defined?(ActiveRecord::TestFixtures)
|
9
|
+
include ActiveRecord::TestFixtures
|
10
|
+
end
|
11
|
+
# Set our fixture path
|
12
|
+
if ActiveRecordTestConnector.able_to_connect
|
13
|
+
self.fixture_path = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
14
|
+
self.use_transactional_fixtures = true
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.fixtures(*args)
|
18
|
+
super if ActiveRecordTestConnector.connected
|
19
|
+
end
|
20
|
+
|
21
|
+
def run(*args)
|
22
|
+
super if ActiveRecordTestConnector.connected
|
23
|
+
end
|
24
|
+
|
25
|
+
# Default so Test::Unit::TestCase doesn't complain
|
26
|
+
def test_truth
|
27
|
+
end
|
28
|
+
|
29
|
+
protected
|
30
|
+
|
31
|
+
def assert_queries(num = 1)
|
32
|
+
$query_count = 0
|
33
|
+
yield
|
34
|
+
ensure
|
35
|
+
assert_equal num, $query_count, "#{$query_count} instead of #{num} queries were executed."
|
36
|
+
end
|
37
|
+
|
38
|
+
def assert_no_queries(&block)
|
39
|
+
assert_queries(0, &block)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
ActiveRecordTestConnector.setup
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_record/version'
|
3
|
+
require 'active_record/fixtures'
|
4
|
+
|
5
|
+
class ActiveRecordTestConnector
|
6
|
+
cattr_accessor :able_to_connect
|
7
|
+
cattr_accessor :connected
|
8
|
+
|
9
|
+
FIXTURES_PATH = File.join(File.dirname(__FILE__), '..', 'fixtures')
|
10
|
+
|
11
|
+
# Set our defaults
|
12
|
+
self.connected = false
|
13
|
+
self.able_to_connect = true
|
14
|
+
|
15
|
+
def self.setup
|
16
|
+
unless self.connected || !self.able_to_connect
|
17
|
+
setup_connection
|
18
|
+
load_schema
|
19
|
+
add_load_path FIXTURES_PATH
|
20
|
+
self.connected = true
|
21
|
+
end
|
22
|
+
rescue Exception => e # errors from ActiveRecord setup
|
23
|
+
$stderr.puts "\nSkipping ActiveRecord tests: #{e}\n\n"
|
24
|
+
self.able_to_connect = false
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def self.add_load_path(path)
|
30
|
+
dep = defined?(ActiveSupport::Dependencies) ? ActiveSupport::Dependencies : ::Dependencies
|
31
|
+
autoload_paths = dep.respond_to?(:autoload_paths) ? dep.autoload_paths : dep.load_paths
|
32
|
+
autoload_paths.unshift path
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.setup_connection
|
36
|
+
db = ENV['DB'].blank?? 'sqlite3' : ENV['DB']
|
37
|
+
|
38
|
+
configurations = YAML.load_file(File.join(File.dirname(__FILE__), '..', 'database.yml'))
|
39
|
+
raise "no configuration for '#{db}'" unless configurations.key? db
|
40
|
+
configuration = configurations[db]
|
41
|
+
|
42
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT) if $0 == 'irb'
|
43
|
+
puts "using #{configuration['adapter']} adapter" unless ENV['DB'].blank?
|
44
|
+
|
45
|
+
gem 'sqlite3-ruby' if 'sqlite3' == db
|
46
|
+
|
47
|
+
ActiveRecord::Base.establish_connection(configuration)
|
48
|
+
ActiveRecord::Base.configurations = { db => configuration }
|
49
|
+
prepare ActiveRecord::Base.connection
|
50
|
+
|
51
|
+
unless Object.const_defined?(:QUOTED_TYPE)
|
52
|
+
Object.send :const_set, :QUOTED_TYPE, ActiveRecord::Base.connection.quote_column_name('type')
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.load_schema
|
57
|
+
ActiveRecord::Base.silence do
|
58
|
+
ActiveRecord::Migration.verbose = false
|
59
|
+
load File.join(FIXTURES_PATH, 'schema.rb')
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.prepare(conn)
|
64
|
+
class << conn
|
65
|
+
IGNORED_SQL = [/^PRAGMA/, /^SELECT currval/, /^SELECT CAST/, /^SELECT @@IDENTITY/, /^SELECT @@ROWCOUNT/, /^SHOW FIELDS /]
|
66
|
+
|
67
|
+
def execute_with_counting(sql, name = nil, &block)
|
68
|
+
$query_count ||= 0
|
69
|
+
$query_count += 1 unless IGNORED_SQL.any? { |r| sql =~ r }
|
70
|
+
execute_without_counting(sql, name, &block)
|
71
|
+
end
|
72
|
+
|
73
|
+
alias_method_chain :execute, :counting
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: change_log
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 1
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 1.0.
|
9
|
+
- 1
|
10
|
+
version: 1.0.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Peter Zhang
|
@@ -15,24 +15,11 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-01-
|
18
|
+
date: 2011-01-25 00:00:00 +13:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
22
|
-
|
23
|
-
prerelease: false
|
24
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
|
-
requirements:
|
27
|
-
- - ">="
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
hash: 3
|
30
|
-
segments:
|
31
|
-
- 0
|
32
|
-
version: "0"
|
33
|
-
type: :development
|
34
|
-
version_requirements: *id001
|
35
|
-
description: A gem for tracking who did what changes and when it happened -- keeps all the maintenance logs
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: A gem for tracking who did what and when it happened -- keeps all the changes done by user into a maintenance log
|
36
23
|
email:
|
37
24
|
- peterz@ncs.co.nz
|
38
25
|
executables: []
|
@@ -53,6 +40,15 @@ files:
|
|
53
40
|
- lib/change_log/controller.rb
|
54
41
|
- lib/change_log/has_change_log.rb
|
55
42
|
- lib/change_log/version.rb
|
43
|
+
- test/boot.rb
|
44
|
+
- test/change_log_test.rb
|
45
|
+
- test/database.yml
|
46
|
+
- test/fixtures/change_logs.yml
|
47
|
+
- test/fixtures/schema.rb
|
48
|
+
- test/fixtures/test.rb
|
49
|
+
- test/lib/activerecord_test_case.rb
|
50
|
+
- test/lib/activerecord_test_connector.rb
|
51
|
+
- test/lib/load_fixtures.rb
|
56
52
|
has_rdoc: true
|
57
53
|
homepage: http://www.ncs.co.nz
|
58
54
|
licenses: []
|
@@ -86,6 +82,14 @@ rubyforge_project: change_log
|
|
86
82
|
rubygems_version: 1.3.7
|
87
83
|
signing_key:
|
88
84
|
specification_version: 3
|
89
|
-
summary: Change log gem
|
90
|
-
test_files:
|
91
|
-
|
85
|
+
summary: Change log gem records every changes for the active record model
|
86
|
+
test_files:
|
87
|
+
- test/boot.rb
|
88
|
+
- test/change_log_test.rb
|
89
|
+
- test/database.yml
|
90
|
+
- test/fixtures/change_logs.yml
|
91
|
+
- test/fixtures/schema.rb
|
92
|
+
- test/fixtures/test.rb
|
93
|
+
- test/lib/activerecord_test_case.rb
|
94
|
+
- test/lib/activerecord_test_connector.rb
|
95
|
+
- test/lib/load_fixtures.rb
|