log_book 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ db/*sqlite
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.3-p286@log_book
data/.rvmrc.example ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.3-p286@log_book
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in log_book.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Fernando Guillen
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # LogBook
2
+
3
+ Storing an events log book.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem "log_book"
10
+
11
+ ### Create the table
12
+
13
+ rails generate guinea_pig:migration
14
+ rake db:migrate
15
+
16
+ ### ActsOnTaggableOn dependency
17
+
18
+ rails generate acts_as_taggable_on:migration
19
+ rake db:migrate
20
+
21
+ ## Usage
22
+
23
+ In any point:
24
+
25
+ LogBook.event(<who executes the action>, <over which object>, <text>, <list of tags>)
26
+
27
+ For example:
28
+
29
+ LogBook.event(current_user, item, "Item canceled", [:purchase, :canceled])
30
+
31
+ ## ActiveRecord integration
32
+
33
+ class MyModel < ActiveRecord::Base
34
+ log_book_log_book
35
+ end
36
+
37
+ MyModel.create! # => LogBook created
38
+ my_model.save! # => LogBook created
39
+ my_model.destroy! # => LogBook created
40
+
41
+ If you want to include _who executes the action_ use the special attribute `log_book_historian`:
42
+
43
+ my_model.log_book_historian = current_user
44
+ my_model.save!
45
+
46
+ ## Sate of the art
47
+
48
+ Beta version but already used in production environments
data/Rakefile ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require "rake/testtask"
4
+
5
+ task :default => :test
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.libs << "."
9
+ t.test_files = FileList["test/**/*_test.rb"]
10
+ t.verbose = true
11
+ end
@@ -0,0 +1,25 @@
1
+ require "rails/generators"
2
+
3
+ class GuineaPig::MigrationGenerator < Rails::Generators::Base
4
+ include Rails::Generators::Migration
5
+
6
+ desc "Generates migration for ABTest model"
7
+
8
+ def self.source_root
9
+ File.join(File.dirname(__FILE__), "templates")
10
+ end
11
+
12
+ def self.next_migration_number(dirname) #:nodoc:
13
+ migration_number_attempt = Time.now.utc.strftime("%Y%m%d%H%M%S")
14
+
15
+ if ActiveRecord::Base.timestamped_migrations && migration_number_attempt > current_migration_number(dirname).to_s
16
+ migration_number_attempt
17
+ else
18
+ serial_migration_number(dirname)
19
+ end
20
+ end
21
+
22
+ def copy_migration
23
+ migration_template "create_log_books.rb", "db/migrate/create_log_books.rb"
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ class CreateLogBookEvents < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :log_book_events do |t|
4
+ t.integer :historian_id
5
+ t.string :historian_type
6
+ t.integer :historizable_id
7
+ t.string :historizable_type
8
+ t.string :text, :null => false
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :log_books
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ class LogBook::Event < ::ActiveRecord::Base
2
+ self.table_name = "log_book_events"
3
+
4
+ attr_accessible :historian, :historizable, :text, :tag_list
5
+
6
+ acts_as_taggable
7
+
8
+ belongs_to :historian, :polymorphic => true
9
+ belongs_to :historizable, :polymorphic => true
10
+
11
+ validates :text, :presence => true
12
+ end
@@ -0,0 +1,45 @@
1
+ module LogBook::Plugin
2
+ def self.included(base)
3
+ base.send :extend, ClassMethods
4
+ base.send :include, InstanceMethods
5
+ end
6
+
7
+ module ClassMethods
8
+ def log_book
9
+ after_create :log_book_event_on_create
10
+ after_update :log_book_event_on_update
11
+ after_destroy :log_book_event_on_destroy
12
+
13
+ attr_accessor :log_book_historian
14
+ end
15
+ end
16
+
17
+ module InstanceMethods
18
+ def log_book_event_on_create
19
+ LogBook.created(self.log_book_historian, self)
20
+ end
21
+
22
+ def log_book_event_on_update
23
+ LogBook.updated(self.log_book_historian, self)
24
+ end
25
+
26
+ def log_book_event_on_destroy
27
+ LogBook.destroyed(self.log_book_historian, self)
28
+ end
29
+
30
+ def pretty_changes
31
+ result =
32
+ self.previous_changes.reject { |k,v| k == "updated_at" || k =~ /password/ || k == "perishable_token" || k == "persistence_token" }.map do |k,v|
33
+ old_value = v[0]
34
+ new_value = v[1]
35
+
36
+ old_value = old_value.to_s( :localdb ) if old_value.instance_of? ActiveSupport::TimeWithZone
37
+ new_value = new_value.to_s( :localdb ) if new_value.instance_of? ActiveSupport::TimeWithZone
38
+
39
+ "#{k}[#{old_value} -> #{new_value}]"
40
+ end.join( ", " )
41
+
42
+ result
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,3 @@
1
+ module LogBook
2
+ VERSION = "0.0.1"
3
+ end
data/lib/log_book.rb ADDED
@@ -0,0 +1,55 @@
1
+ require "active_record"
2
+ require "acts-as-taggable-on"
3
+ require_relative "log_book/version"
4
+ require_relative "log_book/event"
5
+ require_relative "log_book/plugin"
6
+
7
+
8
+ module LogBook
9
+ OPERATIONS = {
10
+ :create => "create",
11
+ :update => "update",
12
+ :destroy => "destroy"
13
+ }
14
+
15
+ def self.event(historian, historizable, text, tag_list)
16
+ tag_list_composed = []
17
+ tag_list_composed << scope_tag(historian) if historian
18
+ tag_list_composed << kind_tag(historizable) if historizable
19
+ tag_list_composed += [tag_list].flatten if tag_list
20
+
21
+ LogBook::Event.create!(
22
+ :historian => historian,
23
+ :historizable => historizable,
24
+ :text => text,
25
+ :tag_list => tag_list_composed
26
+ )
27
+ end
28
+
29
+ def self.created(historian, historizable)
30
+ LogBook.event(historian, historizable, "#{historizable.class.name} created", LogBook::OPERATIONS[:create])
31
+ end
32
+
33
+ def self.updated(historian, historizable)
34
+ LogBook.event(historian, historizable, "#{historizable.class.name} updated [#{historizable.pretty_changes}]", LogBook::OPERATIONS[:update])
35
+ end
36
+
37
+ def self.destroyed(historian, historizable)
38
+ LogBook.event(historian, historizable, "#{historizable.class.name} destroyed", LogBook::OPERATIONS[:destroy])
39
+ end
40
+
41
+ private
42
+
43
+ def self.scope_tag(historian)
44
+ historian.class.name.underscore
45
+ end
46
+
47
+ def self.kind_tag(historizable)
48
+ historizable.class.name.underscore
49
+ end
50
+ end
51
+
52
+ ActiveSupport.on_load(:active_record) do
53
+ include LogBook::Plugin
54
+ end
55
+
data/log_book.gemspec ADDED
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'log_book/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "log_book"
8
+ spec.version = LogBook::VERSION
9
+ spec.authors = ["Fernando Guillen"]
10
+ spec.email = ["fguillen.mail@gmail.com"]
11
+ spec.description = "Storing an events log book"
12
+ spec.summary = "Storing an events log book"
13
+ spec.homepage = "https://github.com/fguillen/LogBook"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "rails", "~> 3.0"
22
+ spec.add_runtime_dependency "acts-as-taggable-on"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ spec.add_development_dependency "mocha"
27
+ spec.add_development_dependency "sqlite3"
28
+ spec.add_development_dependency "assert_difference"
29
+ end
data/test/db/.keep ADDED
File without changes
Binary file
@@ -0,0 +1,54 @@
1
+ require_relative "test_helper"
2
+
3
+ class LogBookTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ LogBook::Event.destroy_all
6
+ User.destroy_all
7
+ Item.destroy_all
8
+
9
+ @user = User.create!(:name => "User Name")
10
+ @item = Item.create!(:title => "Item Title")
11
+ end
12
+
13
+ def test_event
14
+ assert_difference "LogBook::Event.count", 1 do
15
+ LogBook.event(@user, @item, "Item wadus", LogBook::OPERATIONS[:create])
16
+ end
17
+
18
+ log_book = LogBook::Event.last
19
+ assert_equal(@user, log_book.historian)
20
+ assert_equal(@item, log_book.historizable)
21
+ assert_equal("Item wadus", log_book.text)
22
+ assert_equal(["user", "item", "create"].sort, log_book.tag_list.sort)
23
+ end
24
+
25
+ def test_event_with_nils
26
+ assert_difference "LogBook::Event.count", 1 do
27
+ LogBook.event(nil, nil, "Item wadus", nil)
28
+ end
29
+
30
+ log_book = LogBook::Event.last
31
+ assert_equal(nil, log_book.historian)
32
+ assert_equal(nil, log_book.historizable)
33
+ assert_equal("Item wadus", log_book.text)
34
+ assert_equal([], log_book.tag_list)
35
+ end
36
+
37
+ def test_created
38
+ LogBook.expects(:event).with("historian", @item, "Item created", LogBook::OPERATIONS[:create])
39
+ LogBook.created("historian", @item)
40
+ end
41
+
42
+ def test_updated
43
+ @item.update_attributes!(:title => "Other Title")
44
+
45
+ LogBook.expects(:event).with(@user, @item, "Item updated [title[Item Title -> Other Title]]", LogBook::OPERATIONS[:update])
46
+ LogBook.updated(@user, @item)
47
+ end
48
+
49
+ def test_item_destroyed
50
+ LogBook.expects(:event).with(@user, @item, "Item destroyed", LogBook::OPERATIONS[:destroy])
51
+ LogBook.destroyed(@user, @item)
52
+ end
53
+ end
54
+
@@ -0,0 +1,31 @@
1
+ require_relative "test_helper"
2
+
3
+ class LogBookTest < MiniTest::Unit::TestCase
4
+ def setup
5
+ LogBook::Event.destroy_all
6
+ User.destroy_all
7
+ Item.destroy_all
8
+
9
+ @user = User.create!(:name => "User Name")
10
+ @item = Item.create!(:title => "Item Title")
11
+ end
12
+
13
+ def test_event_on_create
14
+ item = Item.new(:log_book_historian => @user)
15
+ LogBook.expects(:created).with(@user, item)
16
+ item.save!
17
+ end
18
+
19
+ def test_event_on_update
20
+ @item.log_book_historian = @user
21
+ LogBook.expects(:updated).with(@user, @item)
22
+ @item.update_attributes(:title => "Other Title")
23
+ end
24
+
25
+ def test_event_on_destroy
26
+ @item.log_book_historian = @user
27
+ LogBook.expects(:destroyed).with(@user, @item)
28
+ @item.destroy
29
+ end
30
+ end
31
+
data/test/models.rb ADDED
@@ -0,0 +1,6 @@
1
+ class User < ActiveRecord::Base
2
+ end
3
+
4
+ class Item < ActiveRecord::Base
5
+ log_book
6
+ end
data/test/schema.rb ADDED
@@ -0,0 +1,24 @@
1
+ ActiveRecord::Schema.define :version => 0 do
2
+ create_table :users, :force => true do |t|
3
+ t.string :name
4
+ end
5
+
6
+ create_table :items, :force => true do |t|
7
+ t.string :title
8
+ end
9
+
10
+ # acts-as-taggable-on
11
+ # https://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/generators/acts_as_taggable_on/migration/templates/active_record/migration.rb
12
+ create_table :tags do |t|
13
+ t.string :name
14
+ end
15
+
16
+ create_table :taggings do |t|
17
+ t.references :tag
18
+ t.references :taggable, :polymorphic => true
19
+ t.references :tagger, :polymorphic => true
20
+ t.string :context, :limit => 128
21
+
22
+ t.datetime :created_at
23
+ end
24
+ end
@@ -0,0 +1,27 @@
1
+ require "minitest/unit"
2
+ require "minitest/autorun"
3
+ require "mocha/setup"
4
+ require "assert_difference"
5
+ require "active_record"
6
+ require "acts-as-taggable-on"
7
+
8
+ FileUtils.rm("#{File.dirname(__FILE__)}/db/log_book.sqlite", :force => true)
9
+
10
+ ActiveRecord::Base.establish_connection(
11
+ :adapter => "sqlite3",
12
+ :database => "#{File.dirname(__FILE__)}/db/log_book.sqlite"
13
+ )
14
+
15
+ require_relative "../lib/generators/log_book/templates/create_log_book_events"
16
+ CreateLogBookEvents.up
17
+
18
+ require_relative "../lib/log_book"
19
+
20
+ load("#{File.dirname(__FILE__)}/schema.rb")
21
+ load("#{File.dirname(__FILE__)}/models.rb")
22
+
23
+ class MiniTest::Unit::TestCase
24
+ include AssertDifference
25
+ FIXTURES = File.expand_path("#{File.dirname(__FILE__)}/fixtures")
26
+ end
27
+
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: log_book
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Fernando Guillen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-03-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails
16
+ requirement: &70266156350280 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70266156350280
25
+ - !ruby/object:Gem::Dependency
26
+ name: acts-as-taggable-on
27
+ requirement: &70266156349820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70266156349820
36
+ - !ruby/object:Gem::Dependency
37
+ name: bundler
38
+ requirement: &70266156349260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '1.3'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70266156349260
47
+ - !ruby/object:Gem::Dependency
48
+ name: rake
49
+ requirement: &70266156348840 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70266156348840
58
+ - !ruby/object:Gem::Dependency
59
+ name: mocha
60
+ requirement: &70266156348380 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70266156348380
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: &70266156347940 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *70266156347940
80
+ - !ruby/object:Gem::Dependency
81
+ name: assert_difference
82
+ requirement: &70266156347520 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *70266156347520
91
+ description: Storing an events log book
92
+ email:
93
+ - fguillen.mail@gmail.com
94
+ executables: []
95
+ extensions: []
96
+ extra_rdoc_files: []
97
+ files:
98
+ - .gitignore
99
+ - .rvmrc
100
+ - .rvmrc.example
101
+ - Gemfile
102
+ - LICENSE.txt
103
+ - README.md
104
+ - Rakefile
105
+ - lib/generators/log_book/migration_generator.rb
106
+ - lib/generators/log_book/templates/create_log_book_events.rb
107
+ - lib/log_book.rb
108
+ - lib/log_book/event.rb
109
+ - lib/log_book/plugin.rb
110
+ - lib/log_book/version.rb
111
+ - log_book.gemspec
112
+ - test/db/.keep
113
+ - test/db/log_book.sqlite
114
+ - test/history_event_test.rb
115
+ - test/log_book_test.rb
116
+ - test/models.rb
117
+ - test/schema.rb
118
+ - test/test_helper.rb
119
+ homepage: https://github.com/fguillen/LogBook
120
+ licenses:
121
+ - MIT
122
+ post_install_message:
123
+ rdoc_options: []
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ none: false
134
+ requirements:
135
+ - - ! '>='
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ requirements: []
139
+ rubyforge_project:
140
+ rubygems_version: 1.8.15
141
+ signing_key:
142
+ specification_version: 3
143
+ summary: Storing an events log book
144
+ test_files:
145
+ - test/db/.keep
146
+ - test/db/log_book.sqlite
147
+ - test/history_event_test.rb
148
+ - test/log_book_test.rb
149
+ - test/models.rb
150
+ - test/schema.rb
151
+ - test/test_helper.rb