best_boy 0.1.1 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,5 +2,4 @@
2
2
  .rvmrc
3
3
  .bundle
4
4
  Gemfile.lock
5
- pkg/*
6
- /db
5
+ pkg/*
@@ -1,3 +1,7 @@
1
+ ## 0.2.0
2
+ * added charts
3
+ * added event_source to best_boy_events for better logging. see update section in README for update instructions
4
+
1
5
  ## 0.1.0
2
6
 
3
7
  * added backend
@@ -1,4 +1,4 @@
1
- Copyright (c) 2012 cseydel
1
+ Copyright (c) 2012 Absolventa GmbH
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,8 +1,9 @@
1
1
  best_boy
2
2
  ========
3
- [![Build Status](https://secure.travis-ci.org/cseydel/best_boy.png?branch=master)](https://secure.travis-ci.org/cseydel/best_boy)
3
+ [![Build Status](https://secure.travis-ci.org/Absolventa/best_boy.png?branch=master)](https://secure.travis-ci.org/Absolventa/best_boy)
4
4
 
5
5
  A simple event driven logging for ActiveRecord models.
6
+ This gem moved from cseydel/best_boy to absolventa/best_boy
6
7
 
7
8
 
8
9
  What does this gem do?
@@ -46,6 +47,18 @@ Run the migration
46
47
  rake db:migrate
47
48
 
48
49
 
50
+ Update from version 0.1.0
51
+ -------------------------
52
+
53
+ Rerun the generator to get needed migrations
54
+
55
+ rails g best_boy
56
+
57
+ Run the migration
58
+
59
+ rake db:migrate
60
+
61
+
49
62
  Usage
50
63
  -----
51
64
 
@@ -55,11 +68,15 @@ In model context:
55
68
 
56
69
  This will log "create" and "delete" event for each instance.
57
70
 
71
+ If you do not want to selflog create and delete events, maybe because you will sort it semantically with a create source, just deactivate the callback logging by setting the parameter :disable_callbacks to true.
72
+
73
+ has_a_best_boy :disable_callbacks => true
74
+
58
75
  In controller context:
59
76
 
60
- best_boy_event object, event
77
+ best_boy_event object, event, event_source = nil
61
78
 
62
- This will log custom events for a object and a event phrase.
79
+ This will log custom events for a object and a event phrase. You can specify this event with a event_source parameter to log maybe seperate create actions.
63
80
 
64
81
  If no Object is given, it will raise an exception as well as if no event is provided.
65
82
 
@@ -70,6 +87,7 @@ BestBoyEvent table
70
87
  t.integer "owner_id" # owner model id
71
88
  t.string "owner_type" # owner model class type
72
89
  t.string "event" # event (create, delete)
90
+ t.string "event_source" # event_source parameter for specific action tracking
73
91
  t.datetime "updated_at" # last update timestamp
74
92
  t.datetime "created_at" # creation timestamp
75
93
 
@@ -97,15 +115,11 @@ Used gems and resource
97
115
 
98
116
  [Stefan Petre](http://www.eyecon.ro/bootstrap-datepicker) for Datepicker in Twitter Bootstrap style
99
117
 
118
+ [Winston Teo Yong Wei](https://github.com/winston/google_visualr) Google_Visulr in its version 2.1.2
119
+
100
120
  Thanks
101
121
  ------
102
122
 
103
123
  Big thanks to each contributor on Impressionist. This gem helped me a long way to get here in modelling and creating a gem.
104
124
 
105
- Famous last words
106
- -----------------
107
- It's my first gem, be gentle ;)
108
-
109
-
110
-
111
- Copyright (c) 2012 Christoph Seydel. See LICENSE.txt for further details.
125
+ Copyright (c) 2012 Absolventa GmbH. See LICENSE.txt for further details.
@@ -2,42 +2,128 @@ module BestBoy
2
2
  class BestBoyEventsController < BestBoy.base_controller.constantize
3
3
 
4
4
  before_filter BestBoy.before_filter if BestBoy.before_filter.present?
5
+ before_filter :prepare_chart, :only => [:charts]
5
6
  skip_before_filter BestBoy.skip_before_filter if BestBoy.skip_before_filter.present?
6
7
 
7
8
  layout 'best_boy_backend'
8
9
 
9
- helper_method :available_owner_types, :available_events, :available_years, :current_owner_type, :current_event, :current_year, :collection, :statistics, :stats_by_event_and_month
10
+ helper_method :available_owner_types, :available_events, :available_event_sources, :available_years, :current_owner_type,
11
+ :current_event, :current_event_source, :current_year, :collection, :statistics, :stats_by_event_and_month,
12
+ :stats_by_event_source_and_month, :render_chart, :event_source_details, :month_name_array
10
13
 
11
14
  private
12
15
 
13
- def current_owner_type
14
- @current_owner_type ||= available_owner_types.include?(params[:owner_type]) ? params[:owner_type] : available_owner_types.first
16
+ def render_chart(chart, dom)
17
+ chart.to_js(dom).html_safe
15
18
  end
16
19
 
17
- def current_event
18
- @current_event ||= available_events.include?(params[:event]) ? params[:event] : nil
20
+ def week_name_array
21
+ %w(Mon Tue Wed Thu Fri Sat Sun)
22
+ end
23
+
24
+ def month_name_array
25
+ %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
26
+ end
27
+
28
+ def custom_data_count(time)
29
+ scope = BestBoyEvent.where("best_boy_events.owner_type = ?", current_owner_type)
30
+ scope = scope.where("best_boy_events.event = ?", current_event) if current_event.present?
31
+ scope = scope.where("best_boy_events.event_source = ?", current_event_source) if current_event_source.present?
32
+ scope = scope.send("per_#{ current_time_interval == "year" ? "month" : "day" }", time)
33
+ scope.count
34
+ end
35
+
36
+ def time_periode_range
37
+ case current_time_interval
38
+ when "month"
39
+ (0..(Time.days_in_month(Time.zone.now.month) - 1))
40
+ when "week"
41
+ (0..6)
42
+ else
43
+ (0..11)
44
+ end
45
+ end
46
+
47
+ def calculated_point_in_time(periode)
48
+ case current_time_interval
49
+ when "month"
50
+ Time.zone.now.beginning_of_month + periode.days
51
+ when "week"
52
+ Time.zone.now.beginning_of_week + periode.days
53
+ else
54
+ Time.zone.now.beginning_of_year + periode.month
55
+ end
56
+ end
57
+
58
+ def chart_legend_time_name(periode)
59
+ case current_time_interval
60
+ when "year"
61
+ month_name_array[periode]
62
+ when "week"
63
+ week_name_array[periode]
64
+ else
65
+ (periode + 1).to_s
66
+ end
67
+ end
68
+
69
+ def stats_by_event_and_month(event, month)
70
+ date = "1-#{month}-#{current_year}".to_time
71
+ BestBoyEvent.where("best_boy_events.owner_type = ? AND best_boy_events.event = ?", current_owner_type, event).per_month(date).count
72
+ end
73
+
74
+ def stats_by_event_source_and_month(source, month)
75
+ date = "1-#{month}-#{current_year}".to_time
76
+ BestBoyEvent.where("best_boy_events.owner_type = ? AND best_boy_events.event = ? AND best_boy_events.event_source = ?", current_owner_type, current_event, source).per_month(date).count
19
77
  end
20
78
 
21
79
  def current_date
22
80
  @current_date ||= Date.strptime(params[:date], "%d-%m-%Y") if params[:date] rescue nil
23
81
  end
24
82
 
83
+ def current_event
84
+ @current_event ||= available_events.include?(params[:event]) ? params[:event] : nil
85
+ end
86
+
87
+ def current_event_source
88
+ @current_event_source ||= available_event_sources.include?(params[:event_source]) ? params[:event_source] : nil
89
+ end
90
+
91
+ def current_owner_type
92
+ @current_owner_type ||= available_owner_types.include?(params[:owner_type]) ? params[:owner_type] : available_owner_types.first
93
+ end
94
+
95
+ def current_time_interval
96
+ @current_time_interval ||= %w(year month week).include?(params[:time_interval]) ? params[:time_interval] : "year"
97
+ end
98
+
25
99
  def current_year
26
100
  @current_year ||= available_years.include?(params[:year]) ? params[:year] : Time.zone.now.year
27
101
  end
28
102
 
29
- def available_owner_types
30
- @available_owner_types ||= BestBoyEvent.select("DISTINCT best_boy_events.owner_type").order("best_boy_events.owner_type ASC").map(&:owner_type)
103
+ def available_events
104
+ @available_events ||= (
105
+ scope = BestBoyEvent.where("best_boy_events.owner_type = ?", current_owner_type)
106
+ scope = scope.select("best_boy_events.event").order("best_boy_events.event ASC")
107
+ scope = scope.group("best_boy_events.event").map(&:event)
108
+ )
31
109
  end
32
110
 
33
- def available_events
34
- @available_events ||= BestBoyEvent.where("best_boy_events.owner_type = ?", current_owner_type).select("best_boy_events.event").order("best_boy_events.event ASC").group("best_boy_events.event").map(&:event)
111
+ def available_event_sources
112
+ @available_event_sources ||= (
113
+ scope = BestBoyEvent.where("best_boy_events.owner_type = ? AND best_boy_events.event = ?", current_owner_type, current_event)
114
+ scope = scope.select("best_boy_events.event_source").order("best_boy_events.event_source ASC")
115
+ scope = scope.group("best_boy_events.event_source").map(&:event_source)
116
+ )
35
117
  end
36
118
 
37
119
  def available_years
38
120
  @available_years = (BestBoyEvent.order("best_boy_events.created_at ASC").first.created_at.to_date.year..Time.zone.now.year).map{ |year| year.to_s } rescue [Time.zone.now.year]
39
121
  end
40
122
 
123
+ def available_owner_types
124
+ @available_owner_types ||= BestBoyEvent.select("DISTINCT best_boy_events.owner_type").order("best_boy_events.owner_type ASC").map(&:owner_type)
125
+ end
126
+
41
127
  def collection
42
128
  @best_boy_events ||= (
43
129
  scope = BestBoyEvent.where("best_boy_events.owner_type = ?", current_owner_type)
@@ -57,9 +143,23 @@ module BestBoy
57
143
  @statistics
58
144
  end
59
145
 
60
- def stats_by_event_and_month event, month
61
- date = "1-#{month}-#{current_year}".to_time
62
- BestBoyEvent.where("best_boy_events.owner_type = ? AND best_boy_events.event = ?", current_owner_type, event).per_month(date).count
146
+ def event_source_details
147
+ @event_source_details = Array.new
148
+ available_event_sources.each do |source|
149
+ scope = BestBoyEvent.where("best_boy_events.owner_type = ? AND best_boy_events.event = ?", current_owner_type, current_event).where("best_boy_events.event_source = ?", source)
150
+ @event_source_details.push([source, scope.count] + %w(year month week day).map{ |delimiter| scope.send("per_#{delimiter}", Time.zone.now).count })
151
+ end
152
+ @event_source_details
153
+ end
154
+
155
+ def prepare_chart
156
+ data_table = GoogleVisualr::DataTable.new
157
+ data_table.new_column('string', 'time')
158
+ data_table.new_column('number', current_owner_type.to_s)
159
+ time_periode_range.each do |periode|
160
+ data_table.add_row([chart_legend_time_name(periode), custom_data_count(calculated_point_in_time(periode))])
161
+ end
162
+ @chart = GoogleVisualr::Interactive::AreaChart.new(data_table, { width: 900, height: 240, title: "" })
63
163
  end
64
164
  end
65
165
  end
@@ -2,7 +2,7 @@
2
2
  <ul class="nav nav-tabs">
3
3
  <% available_owner_types.each do |owner_type| %>
4
4
  <li class="<%= (current_owner_type == owner_type) ? 'active' : nil %>">
5
- <%= link_to owner_type, (referrer == "stats") ? best_boy_admin_stats_path(:owner_type => owner_type) : best_boy_admin_lists_path(:owner_type => owner_type) %>
5
+ <%= link_to owner_type, send("best_boy_admin_#{referrer}_path", :owner_type => owner_type) %>
6
6
  </li>
7
7
  <% end %>
8
8
  </ul>
@@ -0,0 +1,26 @@
1
+ <% content_for :javascripts do %>
2
+ <script src='http://www.google.com/jsapi'></script>
3
+ <% end %>
4
+
5
+
6
+ <%= form_tag best_boy_admin_charts_path, :method => :get, :id => "chart-form" do %>
7
+ <div class="span3">
8
+ <%= select_tag :owner_type, options_for_select([["Owner", nil]] + available_owner_types, :selected => params[:owner_type]), :onchange => "submit();" %>
9
+ </div>
10
+ <div class="span3">
11
+ <%= select_tag :event, options_for_select([["Event", nil]] + available_events, :selected => params[:event]), :onchange => "submit();" %>
12
+ </div>
13
+ <div class="span3">
14
+ <%= select_tag :event_source, options_for_select([["Event Source", nil]] + available_event_sources, :selected => params[:event_source]), :onchange => "submit();" %>
15
+ </div>
16
+ <div class="span3">
17
+ <%= select_tag :time_interval, options_for_select([["Time Interval", nil], ["yearly", "year"], ["monthly", "month"], ["weekly", "week"]], :selected => params[:time_interval]), :onchange => "submit();" %>
18
+ </div>
19
+ <% end %>
20
+
21
+ <div class="span12">
22
+ <div class="well">
23
+ <div id='chart'></div>
24
+ <%= render_chart(@chart, 'chart') %>
25
+ </div>
26
+ </div>
@@ -0,0 +1,66 @@
1
+ <div class="span12">
2
+ <div class="well">
3
+ <%= link_to "<< back to stats", best_boy_admin_stats_path(:owner_type => current_owner_type) %>
4
+ </div>
5
+ </div>
6
+
7
+ <div class="span12">
8
+ <div class="well">
9
+ <h3>Detailed Statistics</h3>
10
+ <table class="table table-striped table-bordered">
11
+ <thead>
12
+ <tr>
13
+ <th>Source</th>
14
+ <th>overall</th>
15
+ <th>year</th>
16
+ <th>month</th>
17
+ <th>week</th>
18
+ <th>day</th>
19
+ </tr>
20
+ </thead>
21
+ <tbody>
22
+ <% event_source_details.each do |best_boy_event_source| %>
23
+ <tr>
24
+ <% (0..5).each do |key| %>
25
+ <td><%= best_boy_event_source[key] %></td>
26
+ <% end %>
27
+ </tr>
28
+ <% end %>
29
+ </tbody>
30
+ </table>
31
+ </div>
32
+ </div>
33
+
34
+ <div class="span12">
35
+ <div class="well">
36
+ <h3 class="pull-left">Detailed Statistics for <%= current_year %> per month</h3>
37
+
38
+ <div class="pull-right">
39
+ <%= form_tag best_boy_admin_details_path, :method => :get do %>
40
+ <%= hidden_field_tag :owner_type, current_owner_type %>
41
+ <%= hidden_field_tag :event, current_event %>
42
+ <%= select_tag :year, options_for_select(available_years, :selected => current_year), :onchange => "submit();" %>
43
+ <% end %>
44
+ </div>
45
+ <table class="table table-striped table-bordered">
46
+ <thead>
47
+ <tr>
48
+ <th>Event</th>
49
+ <% month_name_array.each do |month| %>
50
+ <th><%= month %></th>
51
+ <% end %>
52
+ </tr>
53
+ </thead>
54
+ <tbody>
55
+ <% available_event_sources.each do |source| %>
56
+ <tr>
57
+ <td><%= source %></td>
58
+ <% %w(1 2 3 4 5 6 7 8 9 10 11 12).each do |month| %>
59
+ <td><%= stats_by_event_source_and_month source, month %></td>
60
+ <% end %>
61
+ </tr>
62
+ <% end %>
63
+ </tbody>
64
+ </table>
65
+ </div>
66
+ </div>
@@ -1,4 +1,3 @@
1
- <%= render "navigation", :referrer => "lists" %>
2
1
  <% content_for :stylesheets do %>
3
2
  <%= stylesheet_link_tag "bootstrap_datepicker" %>
4
3
  <% end %>
@@ -10,6 +9,8 @@
10
9
  </script>
11
10
  <% end %>
12
11
 
12
+ <%= render "navigation", :referrer => "lists" %>
13
+
13
14
  <div class="span12">
14
15
  <div class="well">
15
16
  <h3 class="pull-left">Log</h3>
@@ -17,7 +17,8 @@
17
17
  <tbody>
18
18
  <% statistics.each do |best_boy_event| %>
19
19
  <tr>
20
- <% (0..5).each do |key| %>
20
+ <td><%= link_to best_boy_event[0], best_boy_admin_details_path(:event => best_boy_event[0], :owner_type => current_owner_type) %>
21
+ <% (1..5).each do |key| %>
21
22
  <td><%= best_boy_event[key] %></td>
22
23
  <% end %>
23
24
  </tr>
@@ -33,6 +34,7 @@
33
34
 
34
35
  <div class="pull-right">
35
36
  <%= form_tag best_boy_admin_stats_path, :method => :get do %>
37
+ <%= hidden_field_tag :owner_type, current_owner_type %>
36
38
  <%= select_tag :year, options_for_select(available_years, :selected => current_year), :onchange => "submit();" %>
37
39
  <% end %>
38
40
  </div>
@@ -40,7 +42,7 @@
40
42
  <thead>
41
43
  <tr>
42
44
  <th>Event</th>
43
- <% %w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).each do |month| %>
45
+ <% month_name_array.each do |month| %>
44
46
  <th><%= month %></th>
45
47
  <% end %>
46
48
  </tr>
@@ -39,6 +39,7 @@
39
39
  <ul class="nav">
40
40
  <li><%= link_to "Statistics", best_boy_admin_stats_path %></li>
41
41
  <li><%= link_to "List & Logs", best_boy_admin_lists_path %></li>
42
+ <li><%= link_to "Charts", best_boy_admin_charts_path %></li>
42
43
  </ul>
43
44
  <% if BestBoy.custom_redirect.present? %>
44
45
  <p class="navbar-text pull-right"><%= link_to("back", Rails.application.routes.recognize_path(BestBoy.custom_redirect)) %></p>
@@ -9,7 +9,7 @@ Gem::Specification.new do |s|
9
9
  s.license = ['MIT']
10
10
  s.authors = ["Christoph Seydel"]
11
11
  s.email = ["christoph.seydel@me.com"]
12
- s.homepage = "https://github.com/cseydel/best_boy"
12
+ s.homepage = "https://github.com/absolventa/best_boy"
13
13
  s.summary = %q{a simple event driven logging for models}
14
14
  s.description = %q{Hybrid action logging, consisting of standard and custom logging.}
15
15
 
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.required_rubygems_version = ">= 1.3.6"
18
18
 
19
19
  s.add_dependency('kaminari')
20
+ s.add_dependency('google_visualr')
20
21
 
21
22
  s.add_development_dependency('bundler', '~> 1.1.0')
22
23
  s.add_development_dependency('activerecord')
@@ -2,4 +2,6 @@ Rails.application.routes.draw do |map|
2
2
  get "best_boy_admin" => "best_boy/best_boy_events#index", :as => :best_boy_admin
3
3
  get "best_boy_admin/stats" => "best_boy/best_boy_events#stats", :as => :best_boy_admin_stats
4
4
  get "best_boy_admin/lists" => "best_boy/best_boy_events#lists", :as => :best_boy_admin_lists
5
+ get "best_boy_admin/charts" => "best_boy/best_boy_events#charts", :as => :best_boy_admin_charts
6
+ get "best_boy_admin/details" => "best_boy/best_boy_events#details", :as => :best_boy_admin_details
5
7
  end
Binary file
@@ -1,12 +1,8 @@
1
1
  module BestBoyController
2
2
  module InstanceMethods
3
- def best_boy_event(obj, event)
3
+ def best_boy_event(obj, event, source = nil)
4
4
  if obj.respond_to?("eventable?")
5
- if event.present?
6
- obj.trigger_custom_event(event)
7
- else
8
- raise "There is no event to trigger."
9
- end
5
+ obj.trigger_best_boy_event(event, source)
10
6
  else
11
7
  raise "#{obj.class.to_s} is not a best_boy eventable!"
12
8
  end
@@ -1,5 +1,6 @@
1
1
  require "best_boy"
2
2
  require "rails"
3
+ require "google_visualr"
3
4
 
4
5
  module BestBoy
5
6
  class Engine < Rails::Engine
@@ -20,6 +21,5 @@ module BestBoy
20
21
  include BestBoyController::InstanceMethods
21
22
  end
22
23
  end
23
-
24
24
  end
25
25
  end
@@ -3,11 +3,14 @@ module BestBoy
3
3
  extend ActiveSupport::Concern
4
4
 
5
5
  module ClassMethods
6
- def has_a_best_boy
7
- # meta programming
6
+ attr_accessor :disable_callbacks
7
+ @disable_callbacks = nil
8
+
9
+ def has_a_best_boy(options={})
10
+ # constants
8
11
  #
9
12
  #
10
- include InstanceMethods
13
+ @disable_callbacks = options[:disable_callbacks]
11
14
 
12
15
  # associations
13
16
  #
@@ -20,33 +23,35 @@ module BestBoy
20
23
  after_create :trigger_create_event
21
24
  after_destroy :trigger_destroy_event
22
25
  end
23
- end
24
26
 
25
- module InstanceMethods
26
- def eventable?
27
- true
27
+ def best_boy_disable_callbacks
28
+ @disable_callbacks
28
29
  end
30
+ end
29
31
 
30
- def trigger_create_event
31
- create_best_boy_event_with_type "create"
32
- end
32
+ def eventable?
33
+ true
34
+ end
33
35
 
34
- def trigger_destroy_event
35
- # best_boy_event = BestBoyEvent.new(:event => "destroy")
36
- # best_boy_event.owner_type = self.class.name.to_s
37
- # best_boy_event.save
38
- create_best_boy_event_with_type "destroy"
39
- end
36
+ def trigger_create_event
37
+ return if self.class.best_boy_disable_callbacks
38
+ create_best_boy_event_with_type "create"
39
+ end
40
40
 
41
- def trigger_custom_event(type)
42
- create_best_boy_event_with_type(type.to_s) if type.present?
43
- end
41
+ def trigger_destroy_event
42
+ return if self.class.best_boy_disable_callbacks
43
+ create_best_boy_event_with_type "destroy"
44
+ end
44
45
 
45
- def create_best_boy_event_with_type(type)
46
- best_boy_event = BestBoyEvent.new(:event => type)
47
- best_boy_event.owner = self
48
- best_boy_event.save
49
- end
46
+ def trigger_best_boy_event type, source = nil
47
+ create_best_boy_event_with_type(type, source)
48
+ end
49
+
50
+ def create_best_boy_event_with_type type, source = nil
51
+ raise "nil event is not allowed" if type.blank?
52
+ best_boy_event = BestBoyEvent.new(:event => type, :event_source => source)
53
+ best_boy_event.owner = self
54
+ best_boy_event.save
50
55
  end
51
56
  end
52
57
  end
@@ -22,6 +22,6 @@ class BestBoyEvent < ActiveRecord::Base
22
22
  # attributes
23
23
  #
24
24
  #
25
- attr_accessible :event
25
+ attr_accessible :event, :event_source
26
26
 
27
27
  end
@@ -1,3 +1,3 @@
1
1
  module BestBoy
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -14,7 +14,12 @@ module ActiveRecord
14
14
  end
15
15
 
16
16
  def create_migration_file
17
- migration_template 'create_best_boy_events_table.rb', 'db/migrate/create_best_boy_events_table.rb'
17
+ %w(create_best_boy_events_table.rb add_event_source_to_best_boy_events_table.rb).each do |migration_file|
18
+ destination = "db/migrate/#{migration_file.sub(%r\.rb$\, '')}"
19
+ if not self.class.migration_exists?(File.dirname(destination), File.basename(destination))
20
+ migration_template migration_file, destination
21
+ end
22
+ end
18
23
  end
19
24
  end
20
25
  end
@@ -0,0 +1,11 @@
1
+ class AddEventSourceToBestBoyEventsTable < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :best_boy_events, :event_source, :string
4
+ add_index :best_boy_events, :event_source
5
+ end
6
+
7
+ def self.down
8
+ remove_index :best_boy_events, :event_source
9
+ remove_column :best_boy_events, :event_source
10
+ end
11
+ end
@@ -3,7 +3,9 @@ require "spec_helper"
3
3
  describe BestBoyEvent, 'with creating' do
4
4
  it "should have valid model" do
5
5
  example = Example.create
6
- BestBoyEvent.create(:owner_id => example.id, :owner_type => example.class.name.to_s, :event => "create").should be_valid
6
+ best_boy_event = BestBoyEvent.create(:event => "create")
7
+ best_boy_event.owner = example
8
+ best_boy_event.should be_valid
7
9
  end
8
10
  end
9
11
 
@@ -22,7 +24,7 @@ describe BestBoyEvent, 'with scopes' do
22
24
  ActiveRecord::Base.connection.execute("DELETE FROM 'best_boy_events'")
23
25
  example = Example.create
24
26
  (1..times).each do
25
- example.trigger_custom_event("year_test")
27
+ example.trigger_best_boy_event("year_test")
26
28
  example.best_boy_events.last.update_attribute(:created_at, created_at)
27
29
  end
28
30
  end
@@ -23,6 +23,7 @@ ActiveRecord::Schema.define do
23
23
  t.integer :owner_id
24
24
  t.string :owner_type
25
25
  t.string :event
26
+ t.string :event_source
26
27
  t.timestamps
27
28
  end
28
29
  add_index :best_boy_events, :owner_id
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: best_boy
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.1.1
5
+ version: 0.2.0
6
6
  platform: ruby
7
7
  authors:
8
8
  - Christoph Seydel
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2012-06-21 00:00:00 +02:00
13
+ date: 2012-06-27 00:00:00 +02:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -25,82 +25,93 @@ dependencies:
25
25
  type: :runtime
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: bundler
28
+ name: google_visualr
29
29
  prerelease: false
30
30
  requirement: &id002 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: "0"
36
+ type: :runtime
37
+ version_requirements: *id002
38
+ - !ruby/object:Gem::Dependency
39
+ name: bundler
40
+ prerelease: false
41
+ requirement: &id003 !ruby/object:Gem::Requirement
31
42
  none: false
32
43
  requirements:
33
44
  - - ~>
34
45
  - !ruby/object:Gem::Version
35
46
  version: 1.1.0
36
47
  type: :development
37
- version_requirements: *id002
48
+ version_requirements: *id003
38
49
  - !ruby/object:Gem::Dependency
39
50
  name: activerecord
40
51
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
52
+ requirement: &id004 !ruby/object:Gem::Requirement
42
53
  none: false
43
54
  requirements:
44
55
  - - ">="
45
56
  - !ruby/object:Gem::Version
46
57
  version: "0"
47
58
  type: :development
48
- version_requirements: *id003
59
+ version_requirements: *id004
49
60
  - !ruby/object:Gem::Dependency
50
61
  name: activesupport
51
62
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
63
+ requirement: &id005 !ruby/object:Gem::Requirement
53
64
  none: false
54
65
  requirements:
55
66
  - - ">="
56
67
  - !ruby/object:Gem::Version
57
68
  version: "0"
58
69
  type: :development
59
- version_requirements: *id004
70
+ version_requirements: *id005
60
71
  - !ruby/object:Gem::Dependency
61
72
  name: sqlite3
62
73
  prerelease: false
63
- requirement: &id005 !ruby/object:Gem::Requirement
74
+ requirement: &id006 !ruby/object:Gem::Requirement
64
75
  none: false
65
76
  requirements:
66
77
  - - ~>
67
78
  - !ruby/object:Gem::Version
68
79
  version: 1.3.6
69
80
  type: :development
70
- version_requirements: *id005
81
+ version_requirements: *id006
71
82
  - !ruby/object:Gem::Dependency
72
83
  name: rake
73
84
  prerelease: false
74
- requirement: &id006 !ruby/object:Gem::Requirement
85
+ requirement: &id007 !ruby/object:Gem::Requirement
75
86
  none: false
76
87
  requirements:
77
88
  - - ~>
78
89
  - !ruby/object:Gem::Version
79
90
  version: 0.9.2.2
80
91
  type: :development
81
- version_requirements: *id006
92
+ version_requirements: *id007
82
93
  - !ruby/object:Gem::Dependency
83
94
  name: rspec
84
95
  prerelease: false
85
- requirement: &id007 !ruby/object:Gem::Requirement
96
+ requirement: &id008 !ruby/object:Gem::Requirement
86
97
  none: false
87
98
  requirements:
88
99
  - - ~>
89
100
  - !ruby/object:Gem::Version
90
101
  version: 2.10.0
91
102
  type: :development
92
- version_requirements: *id007
103
+ version_requirements: *id008
93
104
  - !ruby/object:Gem::Dependency
94
105
  name: shoulda
95
106
  prerelease: false
96
- requirement: &id008 !ruby/object:Gem::Requirement
107
+ requirement: &id009 !ruby/object:Gem::Requirement
97
108
  none: false
98
109
  requirements:
99
110
  - - ~>
100
111
  - !ruby/object:Gem::Version
101
112
  version: 3.0.1
102
113
  type: :development
103
- version_requirements: *id008
114
+ version_requirements: *id009
104
115
  description: Hybrid action logging, consisting of standard and custom logging.
105
116
  email:
106
117
  - christoph.seydel@me.com
@@ -121,6 +132,8 @@ files:
121
132
  - Rakefile
122
133
  - app/controllers/best_boy/best_boy_events_controller.rb
123
134
  - app/views/best_boy/best_boy_events/_navigation.html.erb
135
+ - app/views/best_boy/best_boy_events/charts.html.erb
136
+ - app/views/best_boy/best_boy_events/details.html.erb
124
137
  - app/views/best_boy/best_boy_events/index.html.erb
125
138
  - app/views/best_boy/best_boy_events/lists.html.erb
126
139
  - app/views/best_boy/best_boy_events/stats.html.erb
@@ -135,6 +148,7 @@ files:
135
148
  - lib/best_boy/models/active_record/best_boy_event.rb
136
149
  - lib/best_boy/version.rb
137
150
  - lib/generators/active_record/best_boy_generator.rb
151
+ - lib/generators/active_record/templates/add_event_source_to_best_boy_events_table.rb
138
152
  - lib/generators/active_record/templates/create_best_boy_events_table.rb
139
153
  - lib/generators/best_boy_generator.rb
140
154
  - lib/generators/templates/best_boy.rb
@@ -149,7 +163,7 @@ files:
149
163
  - spec/best_boy/eventable_spec.rb
150
164
  - spec/spec_helper.rb
151
165
  has_rdoc: true
152
- homepage: https://github.com/cseydel/best_boy
166
+ homepage: https://github.com/absolventa/best_boy
153
167
  licenses:
154
168
  - - MIT
155
169
  post_install_message: