log_book 0.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/.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