public_activity 0.3.1 → 0.3.2

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/Gemfile CHANGED
@@ -4,8 +4,10 @@ gemspec
4
4
 
5
5
  gem 'rails'
6
6
  gem 'yard'
7
- gem 'i18n'
7
+ gem 'pusher'
8
8
 
9
9
  group :development, :test do
10
10
  gem 'rspec'
11
+ gem 'sqlite3'
12
+ gem 'rspec-rails'
11
13
  end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # PublicActivity
1
+ # PublicActivity ![Build Status](http://travis-ci.org/sbower/public_activity.png)
2
2
 
3
3
  public_activity provides smooth acitivity tracking for your ActiveRecord models in Rails 3.
4
4
  Simply put: it records what has been changed or edited and gives you the ability to present those recorded activities to users - in a similar way Github does it.
@@ -28,6 +28,20 @@ Add 'tracked' to the model you want to keep track of:
28
28
  class Article < ActiveRecord::Base
29
29
  tracked
30
30
  end
31
+
32
+ To default the owner to the current user (optional)
33
+
34
+ #Aplication Controller
35
+ before_filter :define_current_user
36
+
37
+ def define_current_user
38
+ User.current_user = current_user
39
+ end
40
+
41
+ #User.rb (model)
42
+ class User < ActiveRecord::Base
43
+ cattr_accessor :current_user
44
+ end
31
45
 
32
46
  And now, by default create/update/destroy activities are recorded in activities table.
33
47
  To display them you can do a simple query:
@@ -43,15 +57,18 @@ And in your views:
43
57
  <%= activity.text %><br/>
44
58
  <% end %>
45
59
 
46
- The only thing left is to add translations to your locale files, for example:
60
+ The only thing left is to add templates (config/pba.yml), for example:
47
61
 
48
- en:
49
62
  activity:
50
63
  article:
51
64
  create: 'Article has been created'
52
65
  update: 'Someone has edited the article'
53
66
  destroy: 'Some user removed an article!'
54
67
 
68
+ Place this in a file and reference it in a rail initializer.
69
+
70
+ PublicActivity::Activity.template = YAML.load_file("#{RAILS_ROOT}/config/pba.yml")
71
+
55
72
  This is only a basic example, refer to documentation for more options and customization!
56
73
  ## Documentation
57
74
 
data/Rakefile CHANGED
@@ -1,8 +1,11 @@
1
+ require "bundler/gem_tasks"
1
2
  require 'rake'
2
3
  require 'yard'
3
4
  require 'yard/rake/yardoc_task'
4
5
  require 'rspec/core/rake_task'
5
6
 
7
+ task :default => :spec
8
+
6
9
  RSpec::Core::RakeTask.new(:spec) do |t|
7
10
  t.pattern = "./spec/*_spec.rb"
8
11
  end
@@ -1,6 +1,7 @@
1
1
  require 'active_support/concern'
2
2
  require 'active_support/dependencies'
3
3
  require 'active_record'
4
+ require 'pusher'
4
5
  # +public_activity+ keeps track of changes made to models
5
6
  # and allows for easy displaying of them.
6
7
  #
@@ -41,13 +42,14 @@ module PublicActivity
41
42
  autoload :Activity
42
43
  autoload :Tracked
43
44
  autoload :Creation
45
+ autoload :Update
44
46
  autoload :Destruction
45
47
  autoload :VERSION
46
48
  autoload :Common
47
49
 
48
50
  included do
49
51
  include Tracked
50
- include Activist
52
+ include Activist
51
53
  end
52
54
  end
53
55
 
@@ -1,5 +1,5 @@
1
1
  require 'active_record'
2
- require 'i18n'
2
+
3
3
  module PublicActivity
4
4
  # The ActiveRecord model containing
5
5
  # details about recorded activity.
@@ -11,22 +11,21 @@ module PublicActivity
11
11
  # Serialize parameters Hash
12
12
  serialize :parameters, Hash
13
13
 
14
- # Virtual attribute returning already
15
- # translated key with params passed
16
- # to i18n.translate function. You can pass additional Hash
17
- # you want to be passed to translation method. It will be merged with the default ones.
14
+ class_attribute :template
15
+
16
+ # Virtual attribute returning text description of the activity
17
+ # using basic ERB templating
18
18
  #
19
19
  # == Example:
20
20
  #
21
21
  # Let's say you want to show article's title inside Activity message.
22
22
  #
23
- # #config/locales/en.yml
24
- # en:
25
- # activity:
26
- # article:
27
- # create: "Someone has created an article '%{title}'"
28
- # update: "Article '%{title}' has been modified"
29
- # destroy: "Someone deleted article '%{title}'!"
23
+ # #config/pba.yml
24
+ # activity:
25
+ # article:
26
+ # create: "New <%= trackable.name %> article has been created"
27
+ # update: 'Someone modified the article'
28
+ # destroy: 'Someone deleted the article!'
30
29
  #
31
30
  # And in controller:
32
31
  #
@@ -40,8 +39,33 @@ module PublicActivity
40
39
  # Now when you list articles, you should see:
41
40
  # @article.activities.last.text #=> "Someone has created an article 'Rails 3.0.5 released!'"
42
41
  def text(params = {})
43
- parameters.merge! params
44
- I18n.t(key, parameters || {})
42
+ begin
43
+ erb_template = resolveTemplate(key)
44
+ if !erb_template.nil?
45
+ parameters.merge! params
46
+ renderer = ERB.new(erb_template)
47
+ renderer.result(binding)
48
+ else
49
+ "Template not defined"
50
+ end
51
+ rescue
52
+ "Template not defined"
53
+ end
54
+ end
55
+
56
+ private
57
+ def resolveTemplate(key)
58
+ res = nil
59
+ if !self.template.nil?
60
+ key.split(".").each do |k|
61
+ if res.nil?
62
+ res = self.template[k]
63
+ else
64
+ res = res[k]
65
+ end
66
+ end
67
+ end
68
+ res
45
69
  end
46
70
  end
47
71
  end
@@ -19,8 +19,16 @@ module PublicActivity
19
19
  # [params]
20
20
  # Hash with parameters passed directly into i18n.translate method - *optional*
21
21
  #
22
- def create_activity(key, owner = nil, params = {})
23
- self.activities.create(:key => key, :owner => owner, :parameters => params)
22
+ def create_activity(key, owner = nil, params = {})
23
+
24
+ if owner.nil? && ((defined? User) != nil) && User.respond_to?(:current_user)
25
+ owner = User.current_user
26
+ end
27
+
28
+ activity = self.activities.create(:key => key, :owner => owner, :parameters => params)
29
+ if !Pusher.app_id.nil? && !Pusher.key.nil? && !Pusher.secret.nil?
30
+ Pusher['acitivty-channel'].trigger('acitivty-create', {:key => key, :owner => owner, :parameters => params, :text => activity.text, :object => self})
31
+ end
24
32
  end
25
33
 
26
34
  private
@@ -5,7 +5,6 @@ module PublicActivity
5
5
 
6
6
  included do
7
7
  after_create :activity_on_create
8
- after_update :activity_on_update
9
8
  end
10
9
  # Handlers responsible for creating Activities.
11
10
  module InstanceMethods
@@ -15,12 +14,6 @@ module PublicActivity
15
14
  settings = prepare_settings
16
15
  create_activity(settings[:key] || "activity."+self.class.name.parameterize('_')+".create", settings[:owner], settings[:parameters])
17
16
  end
18
-
19
- # Creates activity upon modification of the tracked model
20
- def activity_on_update
21
- settings = prepare_settings
22
- create_activity(settings[:key] || "activity."+self.class.name.parameterize('_')+".update", settings[:owner], settings[:parameters])
23
- end
24
17
  end
25
18
  end
26
19
  end
@@ -96,9 +96,29 @@ module PublicActivity
96
96
  # for a guide on how to manually record activities.
97
97
  def tracked(options = {})
98
98
  include Common
99
- if !options[:skip_defaults]
99
+
100
+ all_options = [:create, :update, :destroy]
101
+
102
+ if !options[:skip_defaults] && !options[:only] && !options[:except]
100
103
  include Creation
101
104
  include Destruction
105
+ include Update
106
+ end
107
+
108
+ if options[:except].is_a? Array
109
+ options[:only] = all_options - options[:except]
110
+ end
111
+
112
+ if options[:only].is_a? Array
113
+ options[:only].each do |opt|
114
+ if opt.eql?(:create)
115
+ include Creation
116
+ elsif opt.eql?(:destroy)
117
+ include Destruction
118
+ elsif opt.eql?(:update)
119
+ include Update
120
+ end
121
+ end
102
122
  end
103
123
 
104
124
  if options[:owner]
@@ -0,0 +1,19 @@
1
+ module PublicActivity
2
+ # Handles creation of Activities upon destruction and update of tracked model.
3
+ module Update
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ after_update :activity_on_update
8
+ end
9
+ # Handlers responsible for updating Activities.
10
+ module InstanceMethods
11
+ private
12
+ # Creates activity upon modification of the tracked model
13
+ def activity_on_update
14
+ settings = prepare_settings
15
+ create_activity(settings[:key] || "activity."+self.class.name.parameterize('_')+".update", settings[:owner], settings[:parameters])
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,4 +1,4 @@
1
1
  module PublicActivity
2
2
  # A constant with gem's version
3
- VERSION = '0.3.1'
3
+ VERSION = '0.3.2'
4
4
  end
@@ -0,0 +1,18 @@
1
+ sqlite3:
2
+ adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
3
+ database: awesome_nested_set.sqlite3.db
4
+ sqlite3mem:
5
+ adapter: <%= "jdbc" if defined? JRUBY_VERSION %>sqlite3
6
+ database: ":memory:"
7
+ postgresql:
8
+ adapter: postgresql
9
+ username: postgres
10
+ password: postgres
11
+ database: public_activity_plugin_test
12
+ min_messages: ERROR
13
+ mysql:
14
+ adapter: mysql2
15
+ host: localhost
16
+ username: root
17
+ password:
18
+ database: public_activity_plugin_test
data/spec/db/schema.rb ADDED
@@ -0,0 +1,27 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+
3
+ create_table :categories, :force => true do |t|
4
+ t.column :name, :string
5
+ end
6
+
7
+ create_table :departments, :force => true do |t|
8
+ t.column :name, :string
9
+ end
10
+
11
+ create_table :notes, :force => true do |t|
12
+ t.column :body, :text
13
+ t.column :category_id, :integer
14
+ end
15
+
16
+ create_table :activities, :force => true do |t|
17
+ t.integer :trackable_id
18
+ t.string :trackable_type
19
+ t.integer :owner_id
20
+ t.string :owner_type
21
+ t.string :key
22
+ t.text :parameters
23
+ t.datetime :created_at
24
+ t.datetime :updated_at
25
+ end
26
+
27
+ end
@@ -0,0 +1,18 @@
1
+ cat1:
2
+ id: 1
3
+ name: Category 1
4
+ cat2:
5
+ id: 2
6
+ name: Category 2
7
+ cat3:
8
+ id: 3
9
+ name: Category 3
10
+ cat4:
11
+ id: 4
12
+ name: Category 4
13
+ cat5:
14
+ id: 5
15
+ name: Category 5
16
+ cat6:
17
+ id: 6
18
+ name: Category 6
@@ -0,0 +1,3 @@
1
+ top:
2
+ id: 1
3
+ name: Dept 1
@@ -0,0 +1,8 @@
1
+ note1:
2
+ id: 1
3
+ body: Note 1
4
+ category_id: 1
5
+ note2:
6
+ id: 2
7
+ body: Note 2
8
+ category_id: 200
@@ -0,0 +1,131 @@
1
+ require 'spec_helper'
2
+
3
+ describe "public_activity" do
4
+ before(:all) do
5
+ self.class.fixtures :categories, :departments, :notes
6
+ end
7
+
8
+ describe "tracked" do
9
+
10
+ it "should create a record in activity table" do
11
+ #we should have no records
12
+ PublicActivity::Activity.count.should == 0
13
+
14
+ lambda do
15
+ category = Category.create(:name => "test cat")
16
+ activity = PublicActivity::Activity.last
17
+ activity.trackable_id.should == category.id
18
+ end.should change(PublicActivity::Activity, :count).by(1)
19
+ end
20
+
21
+ describe "activity model" do
22
+ before(:each) do
23
+ @category = Category.create(:name => "test cat")
24
+ end
25
+
26
+ it "should have a nil owner" do
27
+ activity = PublicActivity::Activity.last
28
+ activity.owner.should be_nil
29
+ end
30
+
31
+ it "should have an owner" do
32
+ department = Department.create(:name => "test dept")
33
+ @category.activity_owner = department
34
+ @category.save
35
+
36
+ activity = PublicActivity::Activity.last
37
+ activity.owner.should_not be_nil
38
+ end
39
+
40
+ it "should have activites" do
41
+ @category.activities.should_not be_nil
42
+ end
43
+
44
+ it "should translate" do
45
+ @category.activities.last.text.should_not be_nil
46
+ @category.activities.last.text.should == "New test cat category has been created"
47
+ end
48
+
49
+ it "should track deletes" do
50
+ lambda do
51
+ @category.destroy
52
+ @category.activities.last.text.should == "Someone deleted the category!"
53
+ end.should change(PublicActivity::Activity, :count).by(1)
54
+ end
55
+
56
+ it "should track updates" do
57
+ lambda do
58
+ @category.name = "new cat"
59
+ @category.save
60
+ @category.activities.last.text.should == "Someone modified the category"
61
+ end.should change(PublicActivity::Activity, :count).by(1)
62
+ end
63
+
64
+ it "should evaluate associations" do
65
+ note = Note.find(1)
66
+ note.body = "New Test"
67
+ note.save
68
+ note.activities.last.text.should == "Someone modified note New Test with category Category 1"
69
+ end
70
+ end
71
+
72
+ describe "tracked options" do
73
+ it "should not track destroy for note (only)" do
74
+ lambda do
75
+ note = Note.find(1)
76
+ note.destroy
77
+ end.should change(PublicActivity::Activity, :count).by(0)
78
+ end
79
+
80
+ it "should not track create for department (except)" do
81
+ lambda do
82
+ dept = Department.find(1)
83
+ dept.name = "new name"
84
+ dept.save
85
+ end.should change(PublicActivity::Activity, :count).by(1)
86
+
87
+ lambda do
88
+ dept = Department.find(1)
89
+ dept.destroy
90
+ end.should change(PublicActivity::Activity, :count).by(1)
91
+
92
+ lambda do
93
+ dept = Department.new
94
+ dept.name = "some name"
95
+ dept.save
96
+ end.should change(PublicActivity::Activity, :count).by(0)
97
+
98
+ end
99
+ end
100
+ end
101
+
102
+ describe "activist" do
103
+
104
+ before(:each) do
105
+ @category = Category.create(:name => "test cat")
106
+ @department = Department.create(:name => "test dept")
107
+ @category.activity_owner = @department
108
+ @category.save
109
+ end
110
+
111
+ it "should have activites" do
112
+ @department.activities.should_not be_nil
113
+ end
114
+ end
115
+
116
+ describe "template failures" do
117
+ it "should not die on nil" do
118
+ PublicActivity::Activity.template = nil
119
+ @category = Category.create(:name => "test cat")
120
+ @category.activities.last.text.should == "Template not defined"
121
+ end
122
+
123
+ it "should evaluate associations" do
124
+ note = Note.find(2)
125
+ note.body = "New Test"
126
+ note.save
127
+ note.activities.last.text.should == "Template not defined"
128
+ end
129
+
130
+ end
131
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,9 +1,34 @@
1
- Bundler.setup(:default, :test)
2
- require File.expand_path('lib/public_activity.rb')
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+ plugin_test_dir = File.dirname(__FILE__)
3
3
 
4
- Dir[File.expand_path('support/*')].each {|f| require f}
4
+ require 'rubygems'
5
+ require 'bundler/setup'
5
6
 
7
+ require 'rspec'
8
+ require 'logger'
9
+
10
+ require 'active_support'
11
+ require 'active_model'
12
+ require 'active_record'
13
+ require 'action_controller'
14
+
15
+ require 'public_activity'
16
+ PublicActivity::Activity.template = YAML.load_file(plugin_test_dir + "/support/pba.yml")
17
+
18
+ ActiveRecord::Base.logger = Logger.new(plugin_test_dir + "/debug.log")
19
+
20
+ require 'yaml'
21
+ require 'erb'
22
+ ActiveRecord::Base.configurations = YAML::load(ERB.new(IO.read(plugin_test_dir + "/db/database.yml")).result)
23
+ ActiveRecord::Base.establish_connection(ENV["DB"] || "sqlite3mem")
24
+ ActiveRecord::Migration.verbose = false
25
+ load(File.join(plugin_test_dir, "db", "schema.rb"))
26
+ I18n.load_path += Dir[plugin_test_dir + "/support/en.yml"]
27
+
28
+ require 'support/models'
29
+
30
+ require 'rspec/rails'
6
31
  RSpec.configure do |config|
7
- config.mock_with :rspec
32
+ config.fixture_path = "#{plugin_test_dir}/fixtures"
33
+ config.use_transactional_fixtures = true
8
34
  end
9
-
@@ -0,0 +1,6 @@
1
+ en:
2
+ activity:
3
+ category:
4
+ create: 'New category has been created'
5
+ update: 'Someone modified the category'
6
+ destroy: 'Someone deleted the category!'
@@ -0,0 +1,14 @@
1
+ class Department < ActiveRecord::Base
2
+ tracked(:except => [:create])
3
+ activist
4
+ end
5
+
6
+ class Category < ActiveRecord::Base
7
+ tracked(:only => [:create, :update, :destroy])
8
+ validates_presence_of :name
9
+ end
10
+
11
+ class Note < ActiveRecord::Base
12
+ tracked(:only => [:update])
13
+ belongs_to :category
14
+ end
@@ -0,0 +1,9 @@
1
+ activity:
2
+ category:
3
+ create: "New <%= trackable.name %> category has been created"
4
+ update: 'Someone modified the category'
5
+ destroy: 'Someone deleted the category!'
6
+ note:
7
+ create: "New note <%= trackable.body %> has been created"
8
+ update: 'Someone modified note <%= trackable.body %> with category <%= trackable.category.name %>'
9
+ destroy: 'Someone deleted the note!'
data/spec/version_spec.rb CHANGED
@@ -5,7 +5,7 @@ describe PublicActivity, 'VERSION' do
5
5
  PublicActivity::VERSION.should_not be_nil
6
6
  end
7
7
 
8
- it 'is frozen' do
9
- PublicActivity::VERSION.frozen?.should be(true)
10
- end
8
+ #it 'is frozen' do
9
+ # PublicActivity::VERSION.frozen?.should be(true)
10
+ #end
11
11
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: public_activity
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,12 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-09-08 00:00:00.000000000 +02:00
14
- default_executable:
13
+ date: 2012-01-19 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: activerecord
18
- requirement: &70011400 !ruby/object:Gem::Requirement
17
+ requirement: &74294530 !ruby/object:Gem::Requirement
19
18
  none: false
20
19
  requirements:
21
20
  - - ! '>='
@@ -23,10 +22,10 @@ dependencies:
23
22
  version: 3.0.0
24
23
  type: :runtime
25
24
  prerelease: false
26
- version_requirements: *70011400
25
+ version_requirements: *74294530
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: activesupport
29
- requirement: &70011140 !ruby/object:Gem::Requirement
28
+ requirement: &74293790 !ruby/object:Gem::Requirement
30
29
  none: false
31
30
  requirements:
32
31
  - - ! '>='
@@ -34,10 +33,10 @@ dependencies:
34
33
  version: 3.0.0
35
34
  type: :runtime
36
35
  prerelease: false
37
- version_requirements: *70011140
36
+ version_requirements: *74293790
38
37
  - !ruby/object:Gem::Dependency
39
38
  name: i18n
40
- requirement: &70010890 !ruby/object:Gem::Requirement
39
+ requirement: &74287740 !ruby/object:Gem::Requirement
41
40
  none: false
42
41
  requirements:
43
42
  - - ! '>='
@@ -45,10 +44,21 @@ dependencies:
45
44
  version: 0.5.0
46
45
  type: :runtime
47
46
  prerelease: false
48
- version_requirements: *70010890
47
+ version_requirements: *74287740
48
+ - !ruby/object:Gem::Dependency
49
+ name: pusher
50
+ requirement: &74287260 !ruby/object:Gem::Requirement
51
+ none: false
52
+ requirements:
53
+ - - ! '>='
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ type: :runtime
57
+ prerelease: false
58
+ version_requirements: *74287260
49
59
  - !ruby/object:Gem::Dependency
50
60
  name: rspec
51
- requirement: &70010690 !ruby/object:Gem::Requirement
61
+ requirement: &74286440 !ruby/object:Gem::Requirement
52
62
  none: false
53
63
  requirements:
54
64
  - - ! '>='
@@ -56,7 +66,7 @@ dependencies:
56
66
  version: '0'
57
67
  type: :development
58
68
  prerelease: false
59
- version_requirements: *70010690
69
+ version_requirements: *74286440
60
70
  description: Smooth activity tracking for your ActiveRecord models. Provides Activity
61
71
  model with details about actions performed by your users, like adding comments,
62
72
  responding etc.
@@ -75,15 +85,24 @@ files:
75
85
  - lib/public_activity/creation.rb
76
86
  - lib/public_activity/destruction.rb
77
87
  - lib/public_activity/tracked.rb
88
+ - lib/public_activity/update.rb
78
89
  - lib/public_activity/version.rb
79
90
  - Gemfile
80
91
  - Rakefile
81
92
  - README.md
82
93
  - MIT-LICENSE
94
+ - spec/db/database.yml
95
+ - spec/db/schema.rb
96
+ - spec/fixtures/categories.yml
97
+ - spec/fixtures/departments.yml
98
+ - spec/fixtures/notes.yml
99
+ - spec/public_activity_spec.rb
83
100
  - spec/spec_helper.rb
101
+ - spec/support/en.yml
102
+ - spec/support/models.rb
103
+ - spec/support/pba.yml
84
104
  - spec/version_spec.rb
85
- has_rdoc: true
86
- homepage: https://github.com/okonski/public_activity
105
+ homepage: https://github.com/pokonski/public_activity
87
106
  licenses: []
88
107
  post_install_message:
89
108
  rdoc_options: []
@@ -103,10 +122,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
103
122
  version: '0'
104
123
  requirements: []
105
124
  rubyforge_project:
106
- rubygems_version: 1.6.2
125
+ rubygems_version: 1.8.10
107
126
  signing_key:
108
127
  specification_version: 3
109
128
  summary: Smooth activity tracking for ActiveRecord models
110
129
  test_files:
130
+ - spec/db/database.yml
131
+ - spec/db/schema.rb
132
+ - spec/fixtures/categories.yml
133
+ - spec/fixtures/departments.yml
134
+ - spec/fixtures/notes.yml
135
+ - spec/public_activity_spec.rb
111
136
  - spec/spec_helper.rb
137
+ - spec/support/en.yml
138
+ - spec/support/models.rb
139
+ - spec/support/pba.yml
112
140
  - spec/version_spec.rb
141
+ has_rdoc: