public_activity 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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: