auditrail 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.bundle/config +2 -0
- data/.gitignore +3 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +73 -0
- data/README.md +93 -0
- data/Rakefile +12 -0
- data/auditrail.gemspec +25 -0
- data/lib/auditrail.rb +85 -0
- data/lib/auditrail/version.rb +3 -0
- data/lib/generators/migrations.rb +16 -0
- data/lib/generators/model.rb +14 -0
- data/lib/generators/templates/audit_model.rb +15 -0
- data/lib/generators/templates/audits_table.rb +17 -0
- data/spec/auditrail_spec.rb +155 -0
- data/spec/migrations_spec.rb +14 -0
- data/spec/model_generator_spec.rb +15 -0
- data/spec/spec_helper.rb +18 -0
- data/spec/support/active_record.rb +62 -0
- metadata +142 -0
data/.bundle/config
ADDED
data/.gitignore
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm 1.9.2@auditrail --create
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
auditrail (0.0.1)
|
5
|
+
activerecord (~> 3.0.1)
|
6
|
+
railties (~> 3.0.1)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
abstract (1.0.0)
|
12
|
+
actionpack (3.0.3)
|
13
|
+
activemodel (= 3.0.3)
|
14
|
+
activesupport (= 3.0.3)
|
15
|
+
builder (~> 2.1.2)
|
16
|
+
erubis (~> 2.6.6)
|
17
|
+
i18n (~> 0.4)
|
18
|
+
rack (~> 1.2.1)
|
19
|
+
rack-mount (~> 0.6.13)
|
20
|
+
rack-test (~> 0.5.6)
|
21
|
+
tzinfo (~> 0.3.23)
|
22
|
+
activemodel (3.0.3)
|
23
|
+
activesupport (= 3.0.3)
|
24
|
+
builder (~> 2.1.2)
|
25
|
+
i18n (~> 0.4)
|
26
|
+
activerecord (3.0.3)
|
27
|
+
activemodel (= 3.0.3)
|
28
|
+
activesupport (= 3.0.3)
|
29
|
+
arel (~> 2.0.2)
|
30
|
+
tzinfo (~> 0.3.23)
|
31
|
+
activesupport (3.0.3)
|
32
|
+
arel (2.0.6)
|
33
|
+
builder (2.1.2)
|
34
|
+
diff-lcs (1.1.2)
|
35
|
+
erubis (2.6.6)
|
36
|
+
abstract (>= 1.0.0)
|
37
|
+
i18n (0.5.0)
|
38
|
+
rack (1.2.1)
|
39
|
+
rack-mount (0.6.13)
|
40
|
+
rack (>= 1.0.0)
|
41
|
+
rack-test (0.5.6)
|
42
|
+
rack (>= 1.0)
|
43
|
+
railties (3.0.3)
|
44
|
+
actionpack (= 3.0.3)
|
45
|
+
activesupport (= 3.0.3)
|
46
|
+
rake (>= 0.8.7)
|
47
|
+
thor (~> 0.14.4)
|
48
|
+
rake (0.8.7)
|
49
|
+
rspec (2.0.1)
|
50
|
+
rspec-core (~> 2.0.1)
|
51
|
+
rspec-expectations (~> 2.0.1)
|
52
|
+
rspec-mocks (~> 2.0.1)
|
53
|
+
rspec-core (2.0.1)
|
54
|
+
rspec-expectations (2.0.1)
|
55
|
+
diff-lcs (>= 1.1.2)
|
56
|
+
rspec-mocks (2.0.1)
|
57
|
+
rspec-core (~> 2.0.1)
|
58
|
+
rspec-expectations (~> 2.0.1)
|
59
|
+
rspec-rails (2.0.1)
|
60
|
+
rspec (~> 2.0.0)
|
61
|
+
sqlite3-ruby (1.3.2)
|
62
|
+
thor (0.14.6)
|
63
|
+
tzinfo (0.3.23)
|
64
|
+
|
65
|
+
PLATFORMS
|
66
|
+
ruby
|
67
|
+
|
68
|
+
DEPENDENCIES
|
69
|
+
activerecord (~> 3.0.1)
|
70
|
+
auditrail!
|
71
|
+
railties (~> 3.0.1)
|
72
|
+
rspec-rails (~> 2.0.1)
|
73
|
+
sqlite3-ruby
|
data/README.md
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# auditrail
|
2
|
+
An easy and unobtrusive way to track changes on Active Record models.
|
3
|
+
|
4
|
+
|
5
|
+
## How it works
|
6
|
+
This will generate a table named **audits**. **auditrail** will save an *audit entry* each time
|
7
|
+
an *audited model* changes.
|
8
|
+
|
9
|
+
You can find an example application that shows how to use **auditrail**
|
10
|
+
[here](https://github.com/MGalv/auditrails_test_app).
|
11
|
+
|
12
|
+
|
13
|
+
## Installing
|
14
|
+
It has only been tested on rails3, in order to install it do:
|
15
|
+
|
16
|
+
gem install auditrail
|
17
|
+
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
First run the generator to create the *audits* table:
|
21
|
+
|
22
|
+
rails g auditrail:create
|
23
|
+
|
24
|
+
That will create a migration. Now Simply add *auditable* to your models like this:
|
25
|
+
|
26
|
+
class User < ActiveRecord::Base
|
27
|
+
auditable
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
### Options
|
32
|
+
You can define parameter options with a block.
|
33
|
+
|
34
|
+
#### for_attributes
|
35
|
+
Using *for_attributes* you select the fields that you want to be audited. For example:
|
36
|
+
|
37
|
+
auditable do
|
38
|
+
for_attributes "name", "email"
|
39
|
+
end
|
40
|
+
|
41
|
+
This will create an *audit entry* by each time that the fields *name* or *email* change.
|
42
|
+
|
43
|
+
#### by_user
|
44
|
+
Using *by_user* you control who was the *action invoker* or *fields modifier*:
|
45
|
+
|
46
|
+
auditable do
|
47
|
+
by_user "user"
|
48
|
+
end
|
49
|
+
|
50
|
+
Also, you can call the method *by_user* with a block as parameter. For example:
|
51
|
+
|
52
|
+
auditable do
|
53
|
+
by_user do
|
54
|
+
"user"
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
This way you may dynamically control what will be saved as the *action invoker* or
|
59
|
+
*fields modifier*.
|
60
|
+
|
61
|
+
|
62
|
+
# Development
|
63
|
+
If you want to make changes to the gem, then fork it, and first install bundler:
|
64
|
+
|
65
|
+
gem install bundler
|
66
|
+
|
67
|
+
Afterwards, install the bundle:
|
68
|
+
|
69
|
+
bundle install
|
70
|
+
|
71
|
+
|
72
|
+
## Running the test suite
|
73
|
+
Simply run:
|
74
|
+
|
75
|
+
rake
|
76
|
+
|
77
|
+
|
78
|
+
# Changelog
|
79
|
+
Nothing yet.
|
80
|
+
|
81
|
+
|
82
|
+
# To Do
|
83
|
+
* Refactor auditrail.rb and its tests.
|
84
|
+
* Let the implementor configure where to store the audits.
|
85
|
+
* What the audit table name will be.
|
86
|
+
|
87
|
+
# About the Author
|
88
|
+
[Crowd Interactive](http://www.crowdint.com) is an American web design and development
|
89
|
+
company that happens to work in Colima, Mexico. We specialize in building and growing
|
90
|
+
online retail stores. We don’t work with everyone – just companies we believe in. Call
|
91
|
+
us today to see if there’s a fit.
|
92
|
+
|
93
|
+
Find more info [here](http://www.crowdint.com)!
|
data/Rakefile
ADDED
data/auditrail.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "auditrail/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "auditrail"
|
7
|
+
s.version = Auditrail::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Luis Galaviz", "Emmanuel Delgado"]
|
10
|
+
s.email = ["emmanuel@crowdint.com", "luis.galaviz@crowdint.com"]
|
11
|
+
s.homepage = ""
|
12
|
+
s.summary = %q{Audits models using serialization}
|
13
|
+
s.description = %q{Audits models using serialization}
|
14
|
+
|
15
|
+
s.rubyforge_project = "auditrail"
|
16
|
+
s.add_dependency("activerecord", "~> 3.0.1")
|
17
|
+
s.add_dependency("railties", "~> 3.0.1")
|
18
|
+
s.add_development_dependency("rspec-rails", "~> 2.0.1")
|
19
|
+
s.add_development_dependency("sqlite3-ruby")
|
20
|
+
|
21
|
+
s.files = `git ls-files`.split("\n")
|
22
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
23
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
24
|
+
s.require_paths = ["lib"]
|
25
|
+
end
|
data/lib/auditrail.rb
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'active_support/concern'
|
3
|
+
require 'yaml'
|
4
|
+
require 'generators/migrations'
|
5
|
+
require 'generators/model'
|
6
|
+
|
7
|
+
module Auditrail
|
8
|
+
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
module ClassMethods
|
12
|
+
|
13
|
+
class AuditOptions
|
14
|
+
|
15
|
+
def initialize(&block)
|
16
|
+
instance_eval &block if block
|
17
|
+
end
|
18
|
+
|
19
|
+
def user
|
20
|
+
@user
|
21
|
+
end
|
22
|
+
|
23
|
+
def attributes
|
24
|
+
@attributes
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
def by_user(user = nil, &block)
|
29
|
+
@user = block ? block.call : user
|
30
|
+
end
|
31
|
+
|
32
|
+
def for_attributes(*attributes)
|
33
|
+
@attributes = attributes
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
def auditable(&block)
|
39
|
+
audit_options = block ? AuditOptions.new(&block) : AuditOptions.new
|
40
|
+
|
41
|
+
class_eval do
|
42
|
+
before_create do
|
43
|
+
track_changes(:creating, audit_options.user) if attributes_changed?(*audit_options.attributes)
|
44
|
+
end
|
45
|
+
|
46
|
+
before_update do
|
47
|
+
track_changes(:updating, audit_options.user) if attributes_changed?(*audit_options.attributes)
|
48
|
+
end
|
49
|
+
|
50
|
+
after_save do
|
51
|
+
save_tracked_changes if attributes_changed?(*audit_options.attributes)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
|
59
|
+
module InstanceMethods
|
60
|
+
|
61
|
+
private
|
62
|
+
def attributes_changed?(*options)
|
63
|
+
(options - changes.keys) != options || options.empty?
|
64
|
+
end
|
65
|
+
|
66
|
+
|
67
|
+
def track_changes(*options)
|
68
|
+
action = options[0]
|
69
|
+
@audit = Audit.new
|
70
|
+
@audit.dumped_changes = YAML.dump(changes)
|
71
|
+
@audit.model_changed = self.class
|
72
|
+
@audit.action = action
|
73
|
+
@audit.invoker = YAML.dump(options[1])
|
74
|
+
end
|
75
|
+
|
76
|
+
def save_tracked_changes
|
77
|
+
@audit.element_id = id
|
78
|
+
@audit.save
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
ActiveRecord::Base.send(:include, Auditrail)
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module Auditrail
|
5
|
+
module Generators
|
6
|
+
class MigrationsGenerator < Rails::Generators::Base
|
7
|
+
source_root File.expand_path("templates", File.dirname(__FILE__))
|
8
|
+
|
9
|
+
def prepare
|
10
|
+
migrations_dir = File.join("db", "migrate")
|
11
|
+
file_name = ::ActiveRecord::Generators::Base.next_migration_number(migrations_dir)
|
12
|
+
copy_file("audits_table.rb", File.join(migrations_dir, "#{file_name.to_s}_create_audits.rb"))
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/active_record'
|
3
|
+
|
4
|
+
module Auditrail
|
5
|
+
module Generators
|
6
|
+
class ModelGenerator < Rails::Generators::Base
|
7
|
+
source_root File.expand_path("templates", File.dirname(__FILE__))
|
8
|
+
|
9
|
+
def prepare
|
10
|
+
copy_file("audit_model.rb", File.join("app", "models", "audit.rb"))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
class Audit < ActiveRecord::Base
|
4
|
+
def action_invoker
|
5
|
+
YAML.load(invoker)
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.model_filter(model_changed)
|
9
|
+
where("model_changed = ?", model_changed.to_s.camelize)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.action_filter(action)
|
13
|
+
where("action = ?", action.to_s)
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class CreateAudits < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :audits do |t|
|
4
|
+
t.string :dumped_changes
|
5
|
+
t.string :action
|
6
|
+
t.string :model_changed
|
7
|
+
t.integer :element_id
|
8
|
+
t.string :invoker
|
9
|
+
|
10
|
+
t.timestamps
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.down
|
15
|
+
drop_table :audits
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,155 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'yaml'
|
3
|
+
require 'support/active_record'
|
4
|
+
|
5
|
+
describe 'A test class' do
|
6
|
+
include Auditrail::Test::ActiveRecord
|
7
|
+
|
8
|
+
before do
|
9
|
+
connection_open
|
10
|
+
generate_migration
|
11
|
+
migrate
|
12
|
+
|
13
|
+
# the blocked passed to auditable will determine the action invoker
|
14
|
+
# that will be serialized
|
15
|
+
@test_class.class_eval do
|
16
|
+
auditable do
|
17
|
+
# When using the options by_user you can also pass the parameters as a block.
|
18
|
+
# by_user 465
|
19
|
+
# or
|
20
|
+
# by_user do
|
21
|
+
# 465
|
22
|
+
# end
|
23
|
+
|
24
|
+
by_user 465
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
after do
|
30
|
+
clean_tmp_path
|
31
|
+
connection_close
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'its class should be auditable' do
|
35
|
+
it 'contains an auditable method' do
|
36
|
+
@test_class.should respond_to(:auditable)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
context 'basic Audit behavior' do
|
41
|
+
|
42
|
+
before do
|
43
|
+
@test_class.create(:name => "Text")
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'creates a new object' do
|
47
|
+
|
48
|
+
it "should track the changes in the Test object" do
|
49
|
+
audit_changes = @audit_class.first.dumped_changes
|
50
|
+
changes_hash = YAML.load(audit_changes)
|
51
|
+
changes_hash["name"][0].should eq(nil)
|
52
|
+
changes_hash["name"][1].should eq("Text")
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should receive a creating status" do
|
56
|
+
@audit_class.first.action.should eq("creating")
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should save the model name of the audited object" do
|
60
|
+
@audit_class.first.model_changed.should eq("Test")
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'should save the id of the original affected object' do
|
64
|
+
instance = @test_class.first
|
65
|
+
@audit_class.first.element_id.should eq(instance.id)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should return the action invoker' do
|
69
|
+
@audit_class.first.action_invoker.should eq(465)
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
context 'updates an existing object' do
|
75
|
+
it "should receive a creating status" do
|
76
|
+
instance = @test_class.first
|
77
|
+
instance.name = "Text change"
|
78
|
+
instance.save
|
79
|
+
@audit_class.last.action.should eq("updating")
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
|
85
|
+
context "basic query content behavior" do
|
86
|
+
|
87
|
+
before do
|
88
|
+
@user_class.class_eval do
|
89
|
+
auditable
|
90
|
+
end
|
91
|
+
10.times do
|
92
|
+
@test_class.create(:name => "Text")
|
93
|
+
end
|
94
|
+
|
95
|
+
5.times do |item_number|
|
96
|
+
@user_class.create(:name => "User #{item_number}", :age => 15 + item_number, :email => "abc#{item_number}@abc.com")
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should find the audits by model" do
|
101
|
+
@audit_class.model_filter(:user).should have_exactly(5).items
|
102
|
+
@audit_class.model_filter(:test).should have_exactly(10).items
|
103
|
+
@audit_class.model_filter(:admin).should have_exactly(0).items
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should find the audits by action" do
|
107
|
+
5.times do |item_number|
|
108
|
+
test = @test_class.first
|
109
|
+
test.name = "Text changed #{item_number}"
|
110
|
+
test.save
|
111
|
+
end
|
112
|
+
|
113
|
+
3.times do |item_number|
|
114
|
+
user = @user_class.first
|
115
|
+
user.name = "User 1 name changed #{item_number}"
|
116
|
+
user.save
|
117
|
+
end
|
118
|
+
|
119
|
+
@audit_class.action_filter(:creating).should have_exactly(15).items
|
120
|
+
@audit_class.action_filter(:updating).should have_exactly(8).items
|
121
|
+
@audit_class.action_filter(:other).should have_exactly(0).items
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "track changes only for selected attributes" do
|
126
|
+
before do
|
127
|
+
@user_class.class_eval do
|
128
|
+
auditable do
|
129
|
+
for_attributes "name", "email"
|
130
|
+
end
|
131
|
+
end
|
132
|
+
@user_class.create(:name => "Marco", :age => 15, :email => "marco@abc.com")
|
133
|
+
end
|
134
|
+
|
135
|
+
it "should track only for name and email" do
|
136
|
+
user = @user_class.first
|
137
|
+
user.name = "Polo"
|
138
|
+
user.save
|
139
|
+
|
140
|
+
user = @user_class.first
|
141
|
+
user.email = "polo@abc.com"
|
142
|
+
user.save
|
143
|
+
|
144
|
+
@audit_class.all.should have_exactly(3).items
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should not track changes for age" do
|
148
|
+
user = @user_class.first
|
149
|
+
user.age = 16
|
150
|
+
user.save
|
151
|
+
|
152
|
+
@audit_class.all.should have_exactly(1).items
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/active_record'
|
3
|
+
|
4
|
+
describe Auditrail::Generators::MigrationsGenerator do
|
5
|
+
include Auditrail::Test::ActiveRecord
|
6
|
+
|
7
|
+
before {generate_migration}
|
8
|
+
|
9
|
+
after {clean_tmp_path}
|
10
|
+
|
11
|
+
it "should generate the migration for the audits tabble into the db/migrate folder" do
|
12
|
+
Dir.glob(File.join(File.expand_path(File.join(DESTINATION, "db", "migrate")), "*_create_audits.rb")).should have_exactly(1).items
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'support/active_record'
|
3
|
+
|
4
|
+
describe Auditrail::Generators::ModelGenerator do
|
5
|
+
include Auditrail::Test::ActiveRecord
|
6
|
+
|
7
|
+
before { generate_model }
|
8
|
+
|
9
|
+
after {clean_tmp_path}
|
10
|
+
|
11
|
+
it "should generate the Audit model" do
|
12
|
+
file = File.expand_path(File.join(DESTINATION, "app", "models", "audit.rb"))
|
13
|
+
File.exist?(file).should be(true)
|
14
|
+
end
|
15
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__))
|
2
|
+
$:.unshift File.join(File.dirname(__FILE__), '..', 'lib')
|
3
|
+
|
4
|
+
require 'auditrail'
|
5
|
+
require 'generators/migrations'
|
6
|
+
require 'generators/model'
|
7
|
+
require 'rails'
|
8
|
+
require 'fileutils'
|
9
|
+
require 'rake'
|
10
|
+
|
11
|
+
ENV["RAILS_ENV"] = "test"
|
12
|
+
ENV["RAILS_ROOT"] = "tmp"
|
13
|
+
DESTINATION = File.expand_path(File.join("spec","tmp"))
|
14
|
+
ENV['SCHEMA'] = File.join(DESTINATION, "db", "schema.rb")
|
15
|
+
|
16
|
+
module Auditrail
|
17
|
+
class Application < Rails::Application; end
|
18
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
|
3
|
+
module Auditrail
|
4
|
+
module Test
|
5
|
+
module ActiveRecord
|
6
|
+
|
7
|
+
def migrate
|
8
|
+
rake_app = Rake::Application.new
|
9
|
+
Rake.application = rake_app
|
10
|
+
Rake.application.rake_require File.join("active_record", "railties", "databases")
|
11
|
+
Rake::Task.define_task(:environment)
|
12
|
+
|
13
|
+
::ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
|
14
|
+
::ActiveRecord::Migrator.migrate(File.join(DESTINATION, "db", "migrate"), ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
|
15
|
+
rake_app["db:migrate"].invoke if ::ActiveRecord::Base.schema_format == :ruby
|
16
|
+
generate_model
|
17
|
+
load File.join(DESTINATION, 'app', 'models', 'audit.rb')
|
18
|
+
@audit_class = ::Audit
|
19
|
+
end
|
20
|
+
|
21
|
+
def connection_open
|
22
|
+
#::ActiveRecord::Base.logger = Logger.new(STDOUT)
|
23
|
+
::ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
24
|
+
::ActiveRecord::Schema.define(:version => 1) do
|
25
|
+
create_table :tests do |t|
|
26
|
+
t.string :name
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table :users do |t|
|
30
|
+
t.string :name
|
31
|
+
t.string :email
|
32
|
+
t.integer :age
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
@test_class = Object.const_set(:Test, Class.new(::ActiveRecord::Base))
|
37
|
+
@user_class = Object.const_set(:User, Class.new(::ActiveRecord::Base))
|
38
|
+
end
|
39
|
+
|
40
|
+
def connection_close
|
41
|
+
Object.send(:remove_const, :Test)
|
42
|
+
Object.send(:remove_const, :User)
|
43
|
+
::ActiveRecord::Base.connection.tables.each do |table|
|
44
|
+
::ActiveRecord::Base.connection.drop_table(table)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def clean_tmp_path
|
49
|
+
FileUtils.rm_rf(DESTINATION)
|
50
|
+
end
|
51
|
+
|
52
|
+
def generate_migration
|
53
|
+
Auditrail::Generators::MigrationsGenerator.start([] , :destination_root => DESTINATION)
|
54
|
+
end
|
55
|
+
|
56
|
+
def generate_model
|
57
|
+
Auditrail::Generators::ModelGenerator.start([] , :destination_root => DESTINATION)
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: auditrail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: 0.0.1
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Luis Galaviz
|
13
|
+
- Emmanuel Delgado
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-12-22 00:00:00 -06:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: activerecord
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
segments:
|
30
|
+
- 3
|
31
|
+
- 0
|
32
|
+
- 1
|
33
|
+
version: 3.0.1
|
34
|
+
type: :runtime
|
35
|
+
version_requirements: *id001
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: railties
|
38
|
+
prerelease: false
|
39
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
40
|
+
none: false
|
41
|
+
requirements:
|
42
|
+
- - ~>
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
segments:
|
45
|
+
- 3
|
46
|
+
- 0
|
47
|
+
- 1
|
48
|
+
version: 3.0.1
|
49
|
+
type: :runtime
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
52
|
+
name: rspec-rails
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
55
|
+
none: false
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
segments:
|
60
|
+
- 2
|
61
|
+
- 0
|
62
|
+
- 1
|
63
|
+
version: 2.0.1
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: sqlite3-ruby
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
type: :development
|
78
|
+
version_requirements: *id004
|
79
|
+
description: Audits models using serialization
|
80
|
+
email:
|
81
|
+
- emmanuel@crowdint.com
|
82
|
+
- luis.galaviz@crowdint.com
|
83
|
+
executables: []
|
84
|
+
|
85
|
+
extensions: []
|
86
|
+
|
87
|
+
extra_rdoc_files: []
|
88
|
+
|
89
|
+
files:
|
90
|
+
- .bundle/config
|
91
|
+
- .gitignore
|
92
|
+
- .rvmrc
|
93
|
+
- Gemfile
|
94
|
+
- Gemfile.lock
|
95
|
+
- README.md
|
96
|
+
- Rakefile
|
97
|
+
- auditrail.gemspec
|
98
|
+
- lib/auditrail.rb
|
99
|
+
- lib/auditrail/version.rb
|
100
|
+
- lib/generators/migrations.rb
|
101
|
+
- lib/generators/model.rb
|
102
|
+
- lib/generators/templates/audit_model.rb
|
103
|
+
- lib/generators/templates/audits_table.rb
|
104
|
+
- spec/auditrail_spec.rb
|
105
|
+
- spec/migrations_spec.rb
|
106
|
+
- spec/model_generator_spec.rb
|
107
|
+
- spec/spec_helper.rb
|
108
|
+
- spec/support/active_record.rb
|
109
|
+
has_rdoc: true
|
110
|
+
homepage: ""
|
111
|
+
licenses: []
|
112
|
+
|
113
|
+
post_install_message:
|
114
|
+
rdoc_options: []
|
115
|
+
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
none: false
|
120
|
+
requirements:
|
121
|
+
- - ">="
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
segments:
|
124
|
+
- 0
|
125
|
+
version: "0"
|
126
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
127
|
+
none: false
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
segments:
|
132
|
+
- 0
|
133
|
+
version: "0"
|
134
|
+
requirements: []
|
135
|
+
|
136
|
+
rubyforge_project: auditrail
|
137
|
+
rubygems_version: 1.3.7
|
138
|
+
signing_key:
|
139
|
+
specification_version: 3
|
140
|
+
summary: Audits models using serialization
|
141
|
+
test_files: []
|
142
|
+
|