view_trail 0.3.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/.document +5 -0
- data/.gitignore +5 -0
- data/LICENSE +20 -0
- data/README.md +76 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/features/step_definitions/view_trail_steps.rb +37 -0
- data/features/step_definitions/webrat_steps.rb +119 -0
- data/features/support/env.rb +51 -0
- data/features/support/paths.rb +27 -0
- data/features/view_trail.feature +49 -0
- data/generators/view_trail/templates/create_activities_and_items.rb +21 -0
- data/generators/view_trail/view_trail_generator.rb +10 -0
- data/lib/view_trail/activity.rb +4 -0
- data/lib/view_trail/activity_item.rb +3 -0
- data/lib/view_trail.rb +61 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/view_trail_spec.rb +7 -0
- data/view_trail.gemspec +56 -0
- metadata +75 -0
data/.document
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 Mark Yoon
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# ViewTrail
|
2
|
+
|
3
|
+
ViewTrail lets you track controllers and views that you select for auditing. You can see who look at what (controller/action/params hash) and when.
|
4
|
+
|
5
|
+
## Rails Version
|
6
|
+
|
7
|
+
Works with Rails 2.3.
|
8
|
+
|
9
|
+
## Usage
|
10
|
+
|
11
|
+
class FooController < ActionController::Base
|
12
|
+
has_view_trail :except => :index
|
13
|
+
|
14
|
+
def index
|
15
|
+
end
|
16
|
+
|
17
|
+
def search
|
18
|
+
@results = Model.search(params[:query])
|
19
|
+
|
20
|
+
audit({:results => @results.map(&:id), :flag => "blue"})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Takes :except and :only conditions like other controller filters
|
25
|
+
|
26
|
+
Also allows you to audit an arbitrary key/value hash
|
27
|
+
|
28
|
+
For example: when you visit /foo/search?query=pie
|
29
|
+
|
30
|
+
>> Activities.last.whodiddit #=> (@controller.current_user)
|
31
|
+
>> Activities.last.created_at #=> (date/time of activity)
|
32
|
+
>> Activities.last.controller #=> FooController
|
33
|
+
>> Activities.last.action #=> "search"
|
34
|
+
>> Activities.last.params #=> {:query => "pie"}
|
35
|
+
>> Activities.last.activity_items #=> [{:key => :results, :value => [2, 12, 14]}], [{:key => :flag, :value => "blue"}]
|
36
|
+
|
37
|
+
## Installation
|
38
|
+
|
39
|
+
1. Install ViewTrail as a gem:
|
40
|
+
|
41
|
+
`config.gem 'yoon-view_trail', :lib => 'view_trail', :source => 'http://gems.github.com'`
|
42
|
+
|
43
|
+
2. Create a migration for the `versions` table
|
44
|
+
|
45
|
+
`script/generate view_trail`
|
46
|
+
|
47
|
+
3. Run the migration.
|
48
|
+
|
49
|
+
`rake db:migrate`
|
50
|
+
|
51
|
+
4. Add `has view_trail` to the controllers you want to track
|
52
|
+
|
53
|
+
## Issues
|
54
|
+
|
55
|
+
Please submit issues via GitHub's [Issue Tracker](http://github.com/yoon/view_trail/issues)
|
56
|
+
|
57
|
+
## History
|
58
|
+
|
59
|
+
0.3.1
|
60
|
+
|
61
|
+
Fixed conflict with paper trail whodunnit. To upgrade:
|
62
|
+
|
63
|
+
`rake db:migrate:down`
|
64
|
+
|
65
|
+
remove old migration and re-run
|
66
|
+
|
67
|
+
`script/generate view_trail`
|
68
|
+
`rake db:migrate`
|
69
|
+
|
70
|
+
## Inspiration
|
71
|
+
|
72
|
+
* [PaperTrail](http://github.com/airblade/paper_trail/)
|
73
|
+
|
74
|
+
## Intellectual Property
|
75
|
+
|
76
|
+
Copyright (c) 2009 Mark Yoon. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "view_trail"
|
8
|
+
gem.summary = %Q{View trail tracks controller actions in Rails.}
|
9
|
+
gem.description = %Q{View trail tracks controller actions in Rails.}
|
10
|
+
gem.email = "yoon@northwestern.edu"
|
11
|
+
gem.homepage = "http://github.com/yoon/view_trail"
|
12
|
+
gem.authors = ["Mark Yoon"]
|
13
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
14
|
+
end
|
15
|
+
|
16
|
+
rescue LoadError
|
17
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
18
|
+
end
|
19
|
+
|
20
|
+
require 'spec/rake/spectask'
|
21
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
22
|
+
spec.libs << 'lib' << 'spec'
|
23
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
24
|
+
end
|
25
|
+
|
26
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
27
|
+
spec.libs << 'lib' << 'spec'
|
28
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
29
|
+
spec.rcov = true
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
task :default => :spec
|
34
|
+
|
35
|
+
require 'rake/rdoctask'
|
36
|
+
Rake::RDocTask.new do |rdoc|
|
37
|
+
if File.exist?('VERSION.yml')
|
38
|
+
config = YAML.load(File.read('VERSION.yml'))
|
39
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
40
|
+
else
|
41
|
+
version = ""
|
42
|
+
end
|
43
|
+
|
44
|
+
rdoc.rdoc_dir = 'rdoc'
|
45
|
+
rdoc.title = "view_trail #{version}"
|
46
|
+
rdoc.rdoc_files.include('README*')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
end
|
49
|
+
|
50
|
+
# $:.unshift(File.dirname(__FILE__) + '/../../lib')
|
51
|
+
require 'cucumber/rake/task'
|
52
|
+
Cucumber::Rake::Task.new do |t|
|
53
|
+
t.cucumber_opts = %w{--format pretty}
|
54
|
+
end
|
55
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.1
|
@@ -0,0 +1,37 @@
|
|
1
|
+
Given /^I current user is (\d*)$/ do |id|
|
2
|
+
ApplicationController.cu = id
|
3
|
+
end
|
4
|
+
|
5
|
+
Given /^I have 0 activities$/ do
|
6
|
+
Activity.destroy_all
|
7
|
+
end
|
8
|
+
|
9
|
+
Given /^I ([^ ]*) the ([^ ]*) page$/ do |method, page|
|
10
|
+
visit page, method.to_sym
|
11
|
+
end
|
12
|
+
|
13
|
+
Then /^I should have (\d*) activities$/ do |number|
|
14
|
+
Activity.count.should == number.to_i
|
15
|
+
end
|
16
|
+
|
17
|
+
Then /^the last activity should have "([^\"]*)" ([^ ]*)$/ do |value, key|
|
18
|
+
Activity.last.send(key.to_sym).to_s.should == value
|
19
|
+
end
|
20
|
+
|
21
|
+
Given /^I ([^ ]*) the ([^ ]*) page with params$/ do |method, page|
|
22
|
+
visit(page, method.to_sym, {:check => "yourself"})
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^the last activity should have params$/ do
|
26
|
+
HashWithIndifferentAccess.new(Activity.last.params).should == HashWithIndifferentAccess.new({:check => "yourself"})
|
27
|
+
end
|
28
|
+
|
29
|
+
Then /^the last activity should have data$/ do
|
30
|
+
Activity.last.activity_items.should have(2).activity_items
|
31
|
+
Activity.last.activity_items.first.key.should == "pi"
|
32
|
+
Activity.last.activity_items.first.value.should == [3,1,4,1,5,9]
|
33
|
+
Activity.last.activity_items.last.key.should == "pie"
|
34
|
+
Activity.last.activity_items.last.value.should == ["apple", "blueberry", "pecan", "strawberry"]
|
35
|
+
end
|
36
|
+
|
37
|
+
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "..", "support", "paths"))
|
2
|
+
|
3
|
+
# Commonly used webrat steps
|
4
|
+
# http://github.com/brynary/webrat
|
5
|
+
|
6
|
+
Given /^I am on (.+)$/ do |page_name|
|
7
|
+
visit path_to(page_name)
|
8
|
+
end
|
9
|
+
|
10
|
+
When /^I go to (.+)$/ do |page_name|
|
11
|
+
visit path_to(page_name)
|
12
|
+
end
|
13
|
+
|
14
|
+
When /^I press "([^\"]*)"$/ do |button|
|
15
|
+
click_button(button)
|
16
|
+
end
|
17
|
+
|
18
|
+
When /^I follow "([^\"]*)"$/ do |link|
|
19
|
+
click_link(link)
|
20
|
+
end
|
21
|
+
|
22
|
+
When /^I fill in "([^\"]*)" with "([^\"]*)"$/ do |field, value|
|
23
|
+
fill_in(field, :with => value)
|
24
|
+
end
|
25
|
+
|
26
|
+
When /^I select "([^\"]*)" from "([^\"]*)"$/ do |value, field|
|
27
|
+
select(value, :from => field)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Use this step in conjunction with Rail's datetime_select helper. For example:
|
31
|
+
# When I select "December 25, 2008 10:00" as the date and time
|
32
|
+
When /^I select "([^\"]*)" as the date and time$/ do |time|
|
33
|
+
select_datetime(time)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Use this step when using multiple datetime_select helpers on a page or
|
37
|
+
# you want to specify which datetime to select. Given the following view:
|
38
|
+
# <%= f.label :preferred %><br />
|
39
|
+
# <%= f.datetime_select :preferred %>
|
40
|
+
# <%= f.label :alternative %><br />
|
41
|
+
# <%= f.datetime_select :alternative %>
|
42
|
+
# The following steps would fill out the form:
|
43
|
+
# When I select "November 23, 2004 11:20" as the "Preferred" date and time
|
44
|
+
# And I select "November 25, 2004 10:30" as the "Alternative" date and time
|
45
|
+
When /^I select "([^\"]*)" as the "([^\"]*)" date and time$/ do |datetime, datetime_label|
|
46
|
+
select_datetime(datetime, :from => datetime_label)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Use this step in conjunction with Rail's time_select helper. For example:
|
50
|
+
# When I select "2:20PM" as the time
|
51
|
+
# Note: Rail's default time helper provides 24-hour time-- not 12 hour time. Webrat
|
52
|
+
# will convert the 2:20PM to 14:20 and then select it.
|
53
|
+
When /^I select "([^\"]*)" as the time$/ do |time|
|
54
|
+
select_time(time)
|
55
|
+
end
|
56
|
+
|
57
|
+
# Use this step when using multiple time_select helpers on a page or you want to
|
58
|
+
# specify the name of the time on the form. For example:
|
59
|
+
# When I select "7:30AM" as the "Gym" time
|
60
|
+
When /^I select "([^\"]*)" as the "([^\"]*)" time$/ do |time, time_label|
|
61
|
+
select_time(time, :from => time_label)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Use this step in conjunction with Rail's date_select helper. For example:
|
65
|
+
# When I select "February 20, 1981" as the date
|
66
|
+
When /^I select "([^\"]*)" as the date$/ do |date|
|
67
|
+
select_date(date)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Use this step when using multiple date_select helpers on one page or
|
71
|
+
# you want to specify the name of the date on the form. For example:
|
72
|
+
# When I select "April 26, 1982" as the "Date of Birth" date
|
73
|
+
When /^I select "([^\"]*)" as the "([^\"]*)" date$/ do |date, date_label|
|
74
|
+
select_date(date, :from => date_label)
|
75
|
+
end
|
76
|
+
|
77
|
+
When /^I check "([^\"]*)"$/ do |field|
|
78
|
+
check(field)
|
79
|
+
end
|
80
|
+
|
81
|
+
When /^I uncheck "([^\"]*)"$/ do |field|
|
82
|
+
uncheck(field)
|
83
|
+
end
|
84
|
+
|
85
|
+
When /^I choose "([^\"]*)"$/ do |field|
|
86
|
+
choose(field)
|
87
|
+
end
|
88
|
+
|
89
|
+
When /^I attach the file at "([^\"]*)" to "([^\"]*)"$/ do |path, field|
|
90
|
+
attach_file(field, path)
|
91
|
+
end
|
92
|
+
|
93
|
+
Then /^I should see "([^\"]*)"$/ do |text|
|
94
|
+
response.should contain(text)
|
95
|
+
end
|
96
|
+
|
97
|
+
Then /^I should not see "([^\"]*)"$/ do |text|
|
98
|
+
response.should_not contain(text)
|
99
|
+
end
|
100
|
+
|
101
|
+
Then /^the "([^\"]*)" field should contain "([^\"]*)"$/ do |field, value|
|
102
|
+
field_labeled(field).value.should =~ /#{value}/
|
103
|
+
end
|
104
|
+
|
105
|
+
Then /^the "([^\"]*)" field should not contain "([^\"]*)"$/ do |field, value|
|
106
|
+
field_labeled(field).value.should_not =~ /#{value}/
|
107
|
+
end
|
108
|
+
|
109
|
+
Then /^the "([^\"]*)" checkbox should be checked$/ do |label|
|
110
|
+
field_labeled(label).should be_checked
|
111
|
+
end
|
112
|
+
|
113
|
+
Then /^the "([^\"]*)" checkbox should not be checked$/ do |label|
|
114
|
+
field_labeled(label).should_not be_checked
|
115
|
+
end
|
116
|
+
|
117
|
+
Then /^I should be on (.+)$/ do |page_name|
|
118
|
+
URI.parse(current_url).path.should == path_to(page_name)
|
119
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Sets up the Rails environment for Cucumber
|
2
|
+
ENV['RAILS_ENV'] = 'test'
|
3
|
+
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../../..'
|
4
|
+
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
|
5
|
+
require 'cucumber/rails/world'
|
6
|
+
|
7
|
+
# Sets up webrat
|
8
|
+
require 'webrat'
|
9
|
+
|
10
|
+
Webrat.configure do |config|
|
11
|
+
config.mode = :rails
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'cucumber/rails/rspec'
|
15
|
+
require 'webrat/core/matchers'
|
16
|
+
|
17
|
+
# Sets up controllers
|
18
|
+
require 'application_controller'
|
19
|
+
require 'view_trail'
|
20
|
+
|
21
|
+
class ApplicationController
|
22
|
+
def rescue_action(e)
|
23
|
+
raise e
|
24
|
+
end
|
25
|
+
cattr_accessor :cu
|
26
|
+
# Returns id of hypothetical current user
|
27
|
+
def current_user
|
28
|
+
self.cu
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class FooController < ApplicationController
|
33
|
+
has_view_trail :except => :bar
|
34
|
+
def foo
|
35
|
+
head :ok
|
36
|
+
end
|
37
|
+
def bar
|
38
|
+
head :ok
|
39
|
+
end
|
40
|
+
def baz
|
41
|
+
audit({:pi => [3,1,4,1,5,9], :pie => ["apple", "blueberry", "pecan", "strawberry"]})
|
42
|
+
head :ok
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
# Sets up routes
|
47
|
+
ActionController::Routing::Routes.draw do |map|
|
48
|
+
map.foo "/foo", :controller => "foo", :action => "foo"
|
49
|
+
map.bar "/bar", :controller => "foo", :action => "bar"
|
50
|
+
map.baz "/baz", :controller => "foo", :action => "baz"
|
51
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module NavigationHelpers
|
2
|
+
# Maps a name to a path. Used by the
|
3
|
+
#
|
4
|
+
# When /^I go to (.+)$/ do |page_name|
|
5
|
+
#
|
6
|
+
# step definition in webrat_steps.rb
|
7
|
+
#
|
8
|
+
def path_to(page_name)
|
9
|
+
case page_name
|
10
|
+
|
11
|
+
when /the homepage/
|
12
|
+
default_path
|
13
|
+
|
14
|
+
# Add more mappings here.
|
15
|
+
# Here is a more fancy example:
|
16
|
+
#
|
17
|
+
# when /^(.*)'s profile page$/i
|
18
|
+
# user_profile_path(User.find_by_login($1))
|
19
|
+
|
20
|
+
else
|
21
|
+
raise "Can't find mapping from \"#{page_name}\" to a path.\n" +
|
22
|
+
"Now, go and add a mapping in #{__FILE__}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
World(NavigationHelpers)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
Feature: ViewTrail
|
2
|
+
In order to audit requests made to my app
|
3
|
+
I want to record the controller, action, params, and method
|
4
|
+
|
5
|
+
Background:
|
6
|
+
Given I current user is 312
|
7
|
+
|
8
|
+
Scenario: GET request
|
9
|
+
Given I have 0 activities
|
10
|
+
When I get the foo page
|
11
|
+
Then I should have 1 activities
|
12
|
+
And the last activity should have "312" whodiddit
|
13
|
+
And the last activity should have "foo" action
|
14
|
+
And the last activity should have "foo" controller
|
15
|
+
And the last activity should have "" params
|
16
|
+
|
17
|
+
Scenario: POST request
|
18
|
+
When I post the foo page
|
19
|
+
Then I should have 2 activities
|
20
|
+
And the last activity should have "312" whodiddit
|
21
|
+
And the last activity should have "foo" action
|
22
|
+
|
23
|
+
Scenario: PUT request
|
24
|
+
Given I put the foo page
|
25
|
+
Then I should have 3 activities
|
26
|
+
And the last activity should have "312" whodiddit
|
27
|
+
And the last activity should have "foo" action
|
28
|
+
|
29
|
+
Scenario: DELETE request
|
30
|
+
Given I delete the foo page
|
31
|
+
Then I should have 4 activities
|
32
|
+
And the last activity should have "312" whodiddit
|
33
|
+
And the last activity should have "foo" action
|
34
|
+
|
35
|
+
Scenario: GET request with params
|
36
|
+
Given I get the foo page with params
|
37
|
+
Then I should have 5 activities
|
38
|
+
And the last activity should have params
|
39
|
+
|
40
|
+
Scenario: GET request with params and arbitrary data
|
41
|
+
Given I get the baz page with params
|
42
|
+
Then I should have 6 activities
|
43
|
+
And the last activity should have data
|
44
|
+
And the last activity should have params
|
45
|
+
|
46
|
+
Scenario: GET request on excepted path
|
47
|
+
Given I have 0 activities
|
48
|
+
When I get the bar page
|
49
|
+
Then I should have 0 activities
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateActivitiesAndItems < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :activities do |t|
|
4
|
+
t.string :controller
|
5
|
+
t.string :action
|
6
|
+
t.text :params
|
7
|
+
t.string :whodiddit
|
8
|
+
t.datetime :created_at
|
9
|
+
end
|
10
|
+
create_table :activity_items do |t|
|
11
|
+
t.integer :activity_id
|
12
|
+
t.string :key
|
13
|
+
t.text :value
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.down
|
18
|
+
drop_table :activities
|
19
|
+
drop_table :activity_items
|
20
|
+
end
|
21
|
+
end
|
data/lib/view_trail.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'view_trail/activity'
|
2
|
+
require 'view_trail/activity_item'
|
3
|
+
|
4
|
+
module ViewTrail
|
5
|
+
@@whodiddit = nil
|
6
|
+
|
7
|
+
def self.included(base)
|
8
|
+
base.send :extend, ClassMethods
|
9
|
+
base.before_filter :set_whodiddit
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.whodiddit
|
13
|
+
@@whodiddit.respond_to?(:call) ? @@whodiddit.call : @@whodiddit
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.whodiddit=(value)
|
17
|
+
@@whodiddit = value
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def set_whodiddit
|
23
|
+
@@whodiddit = lambda {
|
24
|
+
self.respond_to?(:current_user) ? self.current_user : nil
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
module ClassMethods
|
29
|
+
def has_view_trail(*conditions)
|
30
|
+
before_filter :set_whodiddit
|
31
|
+
after_filter(:record_activity, conditions)
|
32
|
+
cattr_accessor :view_trail_active
|
33
|
+
self.view_trail_active = true
|
34
|
+
send :include, InstanceMethods
|
35
|
+
end
|
36
|
+
|
37
|
+
def view_trail_off
|
38
|
+
self.view_trail_active = false
|
39
|
+
end
|
40
|
+
def view_trail_on
|
41
|
+
self.view_trail_active = true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module InstanceMethods
|
46
|
+
def audit(items)
|
47
|
+
@activity_items = items
|
48
|
+
end
|
49
|
+
def record_activity
|
50
|
+
if self.class.view_trail_active
|
51
|
+
a = Activity.create(:whodiddit => ViewTrail.whodiddit, :controller => params.delete(:controller), :action => params.delete(:action), :params => params)
|
52
|
+
(@activity_items || {}).each do |k,v|
|
53
|
+
a.activity_items.create(:key => k.to_s, :value => v)
|
54
|
+
end
|
55
|
+
@activity_items = nil
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
ActionController::Base.send :include, ViewTrail
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec'
|
2
|
+
|
3
|
+
# load rails
|
4
|
+
ENV['RAILS_ENV'] = 'test'
|
5
|
+
ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
|
6
|
+
require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
|
7
|
+
|
8
|
+
# load view_trail
|
9
|
+
# $LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
|
+
# $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
11
|
+
# require 'view_trail'
|
12
|
+
|
13
|
+
Spec::Runner.configure do |config|
|
14
|
+
end
|
data/view_trail.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{view_trail}
|
5
|
+
s.version = "0.3.1"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Mark Yoon"]
|
9
|
+
s.date = %q{2009-08-14}
|
10
|
+
s.description = %q{View trail tracks controller actions in Rails.}
|
11
|
+
s.email = %q{yoon@northwestern.edu}
|
12
|
+
s.extra_rdoc_files = [
|
13
|
+
"LICENSE",
|
14
|
+
"README.md"
|
15
|
+
]
|
16
|
+
s.files = [
|
17
|
+
".document",
|
18
|
+
".gitignore",
|
19
|
+
"LICENSE",
|
20
|
+
"README.md",
|
21
|
+
"Rakefile",
|
22
|
+
"VERSION",
|
23
|
+
"features/step_definitions/view_trail_steps.rb",
|
24
|
+
"features/step_definitions/webrat_steps.rb",
|
25
|
+
"features/support/env.rb",
|
26
|
+
"features/support/paths.rb",
|
27
|
+
"features/view_trail.feature",
|
28
|
+
"generators/view_trail/templates/create_activities_and_items.rb",
|
29
|
+
"generators/view_trail/view_trail_generator.rb",
|
30
|
+
"lib/view_trail.rb",
|
31
|
+
"lib/view_trail/activity.rb",
|
32
|
+
"lib/view_trail/activity_item.rb",
|
33
|
+
"spec/spec_helper.rb",
|
34
|
+
"spec/view_trail_spec.rb",
|
35
|
+
"view_trail.gemspec"
|
36
|
+
]
|
37
|
+
s.homepage = %q{http://github.com/yoon/view_trail}
|
38
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
39
|
+
s.require_paths = ["lib"]
|
40
|
+
s.rubygems_version = %q{1.3.4}
|
41
|
+
s.summary = %q{View trail tracks controller actions in Rails.}
|
42
|
+
s.test_files = [
|
43
|
+
"spec/spec_helper.rb",
|
44
|
+
"spec/view_trail_spec.rb"
|
45
|
+
]
|
46
|
+
|
47
|
+
if s.respond_to? :specification_version then
|
48
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
49
|
+
s.specification_version = 3
|
50
|
+
|
51
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
52
|
+
else
|
53
|
+
end
|
54
|
+
else
|
55
|
+
end
|
56
|
+
end
|
metadata
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: view_trail
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Mark Yoon
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-08-14 00:00:00 -05:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description: View trail tracks controller actions in Rails.
|
17
|
+
email: yoon@northwestern.edu
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- LICENSE
|
29
|
+
- README.md
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- features/step_definitions/view_trail_steps.rb
|
33
|
+
- features/step_definitions/webrat_steps.rb
|
34
|
+
- features/support/env.rb
|
35
|
+
- features/support/paths.rb
|
36
|
+
- features/view_trail.feature
|
37
|
+
- generators/view_trail/templates/create_activities_and_items.rb
|
38
|
+
- generators/view_trail/view_trail_generator.rb
|
39
|
+
- lib/view_trail.rb
|
40
|
+
- lib/view_trail/activity.rb
|
41
|
+
- lib/view_trail/activity_item.rb
|
42
|
+
- spec/spec_helper.rb
|
43
|
+
- spec/view_trail_spec.rb
|
44
|
+
- view_trail.gemspec
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/yoon/view_trail
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options:
|
51
|
+
- --charset=UTF-8
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
version: "0"
|
59
|
+
version:
|
60
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ">="
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: "0"
|
65
|
+
version:
|
66
|
+
requirements: []
|
67
|
+
|
68
|
+
rubyforge_project:
|
69
|
+
rubygems_version: 1.3.4
|
70
|
+
signing_key:
|
71
|
+
specification_version: 3
|
72
|
+
summary: View trail tracks controller actions in Rails.
|
73
|
+
test_files:
|
74
|
+
- spec/spec_helper.rb
|
75
|
+
- spec/view_trail_spec.rb
|