activities 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,89 @@
1
+ = Introduction
2
+
3
+ Activities is a gem that enables social activities in ActiveRecord objects.
4
+
5
+ = Install
6
+
7
+ sudo gem install activities
8
+
9
+ You have to create a migration with the following code:
10
+
11
+ create_table :activities do |t|
12
+ t.references :tracker, :polymorphic => true, :null => false
13
+ t.references :trackable, :polymorphic => true, :null => false
14
+ t.string :action, :null => false
15
+ t.text :data, :null => true
16
+ t.timestamps
17
+ end
18
+
19
+ add_index :activities, [:tracker_id, :trackable_id]
20
+ add_index :activities, [:tracker_id, :trackable_id, :action]
21
+
22
+ If you want the source go to http://github.com/fnando/activities
23
+
24
+ = Usage
25
+
26
+ Activities is plugged on associations. So, all you have to do is add something like this:
27
+
28
+ class User < ActiveRecord::Base
29
+ has_many :projects
30
+ activities_for :projects do
31
+ track :renamed, :if => proc {|r| !r.new_record? && r.name_changed? }, :on => :save
32
+ track :create
33
+ track :update
34
+ track :destroy
35
+ end
36
+ end
37
+
38
+ This will add activities when you create, update, destroy a project or the change its name.
39
+
40
+ To retrieve the activities, you can use the association +activities+.
41
+
42
+ @user.activities.all
43
+
44
+ By default, all attributes are stored in a field called +data+. You should overwrite the method
45
+ +to_activity+ and return a hash with the attributes that you really want to be saved.
46
+
47
+ class Project < ActiveRecord::Base
48
+ belongs_to :user
49
+
50
+ def to_activity
51
+ { :name => name, :status => status }
52
+ end
53
+ end
54
+
55
+ To display the activities, you should use the helper +render_activity+.
56
+
57
+ <% for activity in @activities %>
58
+ <%= render_activity @activity %>
59
+ <% end %>
60
+
61
+ The +render_activity+ helper will render a partial as <tt>app/views/activities/TRACKABLE_TYPE/ACTION</tt>.
62
+ So, if you want to render activities fro that project, you should create the following files:
63
+
64
+ app/views/activities/project/_renamed.html.erb
65
+ app/views/activities/project/_create.html.erb
66
+ app/views/activities/project/_update.html.erb
67
+ app/views/activities/project/_destroy.html.erb
68
+
69
+ The activity object will be available and you can display something like this:
70
+
71
+ <p>
72
+ <%= tracker.name %> created the
73
+ repository <%= link_to data[:name], project_path(trackable) %>
74
+ <%= time_ago_in_words data[:created_at] %>
75
+ </p>
76
+
77
+ = License
78
+
79
+ (The MIT License)
80
+
81
+ Copyright © 2010:
82
+
83
+ * Nando Vieira - http://simplesideias.com.br
84
+
85
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
86
+
87
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
88
+
89
+ THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,43 @@
1
+ require "jeweler"
2
+ require "rcov/rcovtask"
3
+ require "rake/testtask"
4
+ require "rake/rdoctask"
5
+ require "lib/activities/version"
6
+
7
+ Rcov::RcovTask.new do |t|
8
+ t.test_files = FileList["test/**/*_test.rb"]
9
+ t.rcov_opts = ["--sort coverage", "--exclude .gem,.bundle,errors.rb"]
10
+
11
+ t.output_dir = "coverage"
12
+ t.libs << "test"
13
+ t.verbose = true
14
+ end
15
+
16
+ Rake::TestTask.new do |t|
17
+ t.libs << "lib"
18
+ t.libs << "test"
19
+ t.test_files = FileList["test/**/*_test.rb"]
20
+ t.verbose = true
21
+ end
22
+
23
+ Rake::RDocTask.new do |rdoc|
24
+ rdoc.main = "README.rdoc"
25
+ rdoc.rdoc_dir = "doc"
26
+ rdoc.title = "Actitivies API"
27
+ rdoc.options += %w[ --line-numbers --inline-source --charset utf-8 ]
28
+ rdoc.rdoc_files.include("README.rdoc")
29
+ rdoc.rdoc_files.include("lib/**/*.rb")
30
+ end
31
+
32
+ JEWEL = Jeweler::Tasks.new do |gem|
33
+ gem.name = "activities"
34
+ gem.email = "fnando.vieira@gmail.com"
35
+ gem.homepage = "http://github.com/fnando/activities"
36
+ gem.authors = ["Nando Vieira"]
37
+ gem.version = Activities::Version::STRING
38
+ gem.summary = "A framework for aggregating social activity."
39
+ gem.add_dependency "activerecord"
40
+ gem.files = FileList["{README,CHANGELOG}.rdoc", "{lib,test}/**/*", "Rakefile"]
41
+ end
42
+
43
+ Jeweler::GemcutterTasks.new
@@ -0,0 +1,14 @@
1
+ require "active_record"
2
+ require "activities/version"
3
+ require "activities/helper"
4
+ require "activities/active_record"
5
+ require "activities/activity"
6
+ require "activities/dsl"
7
+
8
+ module Activities
9
+ end
10
+
11
+ ActiveRecord::Base.class_eval do
12
+ include Activities::ActiveRecord::InstanceMethods
13
+ extend Activities::ActiveRecord::ClassMethods
14
+ end
@@ -0,0 +1,2 @@
1
+ require "activities/active_record/instance_methods"
2
+ require "activities/active_record/class_methods"
@@ -0,0 +1,93 @@
1
+ module Activities
2
+ module ActiveRecord
3
+ module ClassMethods
4
+ # Add a new activity trigger.
5
+ #
6
+ # class User < ActiveRecord::Base
7
+ # has_many :tasks
8
+ #
9
+ # activities_for :tasks do
10
+ # track :create
11
+ # track :update
12
+ # track :destroy
13
+ # end
14
+ # end
15
+ #
16
+ # The above statement will create activities when
17
+ # a <tt>Thing</tt> instance is created, updated or removed.
18
+ #
19
+ # By default, the activity tracker stores all
20
+ # attributes. But you can specify which attributes you want to
21
+ # save. Just overwrite the method <tt>to_activity</tt> on your
22
+ # trackable model.
23
+ #
24
+ # class Task < ActiveRecord::Base
25
+ # belongs_to :project
26
+ #
27
+ # def to_activity
28
+ # { :project_name => project.name, :task_name => name }
29
+ # end
30
+ # end
31
+ #
32
+ # To track custom actions, you need to specify other options.
33
+ # Imagine you want to track when a task is marked as completed.
34
+ # You can add an activity to this action.
35
+ #
36
+ # class User < ActiveRecord::Base
37
+ # has_many :tasks
38
+ #
39
+ # activities_for :tasks do
40
+ # track :completed, :on => :update, :if => proc {|task| task.status_changed? && task.status == "completed" }
41
+ # end
42
+ # end
43
+ #
44
+ # You can also track when an attribute changes:
45
+ #
46
+ # class User < ActiveRecord::Base
47
+ # has_many :projects
48
+ #
49
+ # activities_for :projects do
50
+ # track :renamed, :on => :update, :if => :name_changed?
51
+ # end
52
+ # end
53
+ #
54
+ # There's also an <tt>:unless</tt> option. REMEMBER: you can't use the <tt>:unless</tt> and <tt>:if</tt>
55
+ # options at the same time.
56
+ #
57
+ def activities_for(reflection_name, &block)
58
+ reflection = self.reflections[reflection_name]
59
+ tracker_class = self
60
+
61
+ raise ArgumentError, "#{reflection_name.inspect} is not an existing association" unless reflection
62
+ raise ArgumentError, "no block given" unless block_given?
63
+
64
+ tracker_class.class_eval do
65
+ has_many :activities, :as => :tracker
66
+ end
67
+
68
+ model_class = reflection.class_name.constantize
69
+
70
+ model_class.class_eval do
71
+ unless self.respond_to?(:activity_trackers)
72
+ class << self
73
+ attr_accessor :activity_trackers
74
+ end
75
+
76
+ has_many :activities, :as => :trackable
77
+
78
+ self.activity_trackers = {}
79
+
80
+ after_create :process_activities_on_create
81
+ before_save :process_activities_on_update
82
+ before_destroy :process_activities_on_destroy
83
+ end
84
+ end
85
+
86
+ dsl = Activities::Dsl.new
87
+ dsl.trackable = model_class
88
+ dsl.reflection_name = reflection.primary_key_name.gsub(/_id$/, "")
89
+ dsl.instance_eval(&block)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,55 @@
1
+ module Activities
2
+ module ActiveRecord
3
+ module InstanceMethods
4
+ def to_activity # :nodoc:
5
+ attributes
6
+ end
7
+
8
+ private
9
+ def process_activities(step)
10
+ [self.class.activity_trackers[step]].flatten.compact.each do |options|
11
+ next unless process_activity?(options)
12
+
13
+ ::Activity.create!({
14
+ :tracker => self.send(options[:reflection_name]),
15
+ :trackable => self,
16
+ :action => options[:action].to_s,
17
+ :data => to_activity.symbolize_keys
18
+ })
19
+ end
20
+ end
21
+
22
+ def process_activity?(options)
23
+ if options[:if]
24
+ check_against = true
25
+ callback = options[:if]
26
+ elsif options[:unless]
27
+ check_against = false
28
+ callback = options[:unless]
29
+ else
30
+ return true
31
+ end
32
+
33
+ if callback.respond_to?(:call)
34
+ result = callback[self]
35
+ elsif callback.kind_of?(Symbol)
36
+ result = send(callback)
37
+ end
38
+
39
+ !!result == check_against
40
+ end
41
+
42
+ def process_activities_on_create
43
+ process_activities(:create)
44
+ end
45
+
46
+ def process_activities_on_update
47
+ process_activities(:update) unless new_record?
48
+ end
49
+
50
+ def process_activities_on_destroy
51
+ process_activities(:destroy)
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,5 @@
1
+ class Activity < ::ActiveRecord::Base
2
+ belongs_to :tracker, :polymorphic => true
3
+ belongs_to :trackable, :polymorphic => true
4
+ serialize :data, Hash
5
+ end
@@ -0,0 +1,24 @@
1
+ module Activities
2
+ class Dsl
3
+ attr_accessor :trackable
4
+ attr_accessor :reflection_name
5
+
6
+ def track(action, options = {})
7
+ options = prepare_options(action, options)
8
+ check_validity!(options)
9
+ on = options.delete(:on)
10
+ trackable.activity_trackers[on] ||= []
11
+ trackable.activity_trackers[on] << options.merge(:action => action, :reflection_name => reflection_name)
12
+ end
13
+
14
+ protected
15
+ def prepare_options(action, options = {}) # :nodoc:
16
+ options[:on] ||= action if [:create, :update, :destroy].include?(action)
17
+ options
18
+ end
19
+
20
+ def check_validity!(options) # :nodoc:
21
+ raise ArgumentError, "the track method expects :on to be set" unless [:create, :update, :destroy].include?(options[:on])
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ module Activities
2
+ module Helper
3
+ def render_activity(activity)
4
+ path = "activities/#{activity.trackable_type.underscore}/#{activity.action}"
5
+ locals = {
6
+ :activity => activity,
7
+ :tracker => activity.tracker,
8
+ :trackable => activity.trackable,
9
+ :data => activity.data
10
+ }
11
+ render :partial => path, :locals => locals
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,8 @@
1
+ module Activities
2
+ module Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 0
6
+ STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
7
+ end
8
+ end
@@ -0,0 +1,244 @@
1
+ require "test_helper"
2
+
3
+ class Activities::ActiveRecordTest < Test::Unit::TestCase
4
+ def setup
5
+ %w[User Task Milestone Project].each do |name|
6
+ Object.send(:remove_const, name) rescue nil
7
+ end
8
+ load "resources/models.rb"
9
+
10
+ User.delete_all
11
+ Project.delete_all
12
+ Task.delete_all
13
+ Milestone.delete_all
14
+ Activity.delete_all
15
+
16
+ @user = User.create(:login => "johndoe")
17
+ end
18
+
19
+ def test_models_should_respond_to_activities_for
20
+ assert User.respond_to?(:activities_for)
21
+ end
22
+
23
+ def test_activities_for_expects_an_association
24
+ assert_raise ArgumentError do
25
+ User.activities_for
26
+ end
27
+ end
28
+
29
+ def test_activities_for_expects_a_valid_association
30
+ assert_raise ArgumentError do
31
+ User.activities_for :invalid do
32
+ track :create
33
+ end
34
+ end
35
+ end
36
+
37
+ def test_activities_for_expects_a_block
38
+ assert_raise ArgumentError do
39
+ User.activities_for :projects
40
+ end
41
+ end
42
+
43
+ def test_setup_trackable_class
44
+ User.activities_for(:tasks) do
45
+ track :create
46
+ track :update
47
+ track :destroy
48
+ track :renamed, :on => :update, :if => :name_changed?
49
+ end
50
+
51
+ expected = {
52
+ :create => [{:reflection_name => "user", :action => :create}],
53
+ :update => [
54
+ {:reflection_name => "user", :action => :update},
55
+ {:reflection_name => "user", :action => :renamed, :if => :name_changed?}
56
+ ],
57
+ :destroy => [{:reflection_name => "user", :action => :destroy}]
58
+ }
59
+ assert_equal(expected, Task.activity_trackers)
60
+ end
61
+
62
+ def test_add_multiple_trackers
63
+ User.activities_for(:tasks) { track :create }
64
+ Project.activities_for(:tasks) { track :create }
65
+
66
+ expected = {
67
+ :create => [
68
+ { :reflection_name => "user", :action => :create },
69
+ { :reflection_name => "project", :action => :create }
70
+ ]
71
+ }
72
+ assert_equal(expected, Task.activity_trackers)
73
+ end
74
+
75
+ def test_add_multiple_activities
76
+ User.activities_for(:tasks) { track :create }
77
+ Project.activities_for(:tasks) { track :create }
78
+
79
+ @project = Project.create(:user => @user)
80
+ @task = @project.tasks.create(:user => @user, :name => "New task")
81
+
82
+ assert_equal 1, @user.activities.count(:conditions => {:action => "create"})
83
+ assert_equal 1, @project.activities.count(:conditions => {:action => "create"})
84
+ end
85
+
86
+ def test_store_attributes_for_activity
87
+ User.activities_for(:tasks) do
88
+ track :create
89
+ end
90
+
91
+ @task = @user.tasks.create(:name => "New task")
92
+ @activity = @user.activities.first
93
+
94
+ assert_equal @task.attributes.symbolize_keys, @activity.data
95
+ end
96
+
97
+ def test_activity_for_create
98
+ User.activities_for(:tasks) do
99
+ track :create
100
+ end
101
+
102
+ @task = @user.tasks.create(:name => "New task")
103
+ @task.update_attribute :name, "Updated task"
104
+ @task.destroy
105
+
106
+ assert_equal 1, @user.activities.count(:conditions => {:action => "create"})
107
+ assert_equal 1, @user.activities.count
108
+ end
109
+
110
+ def test_activity_for_destroy
111
+ User.activities_for(:tasks) do
112
+ track :destroy
113
+ end
114
+
115
+ @task = @user.tasks.create(:name => "New task")
116
+ @task.update_attribute :name, "Updated task"
117
+ @task.destroy
118
+
119
+ assert_equal 1, @user.activities.count(:conditions => {:action => "destroy"})
120
+ assert_equal 1, @user.activities.count
121
+ end
122
+
123
+ def test_activity_for_update
124
+ User.activities_for(:tasks) do
125
+ track :update
126
+ end
127
+
128
+ @task = @user.tasks.create(:name => "New task")
129
+ @task.update_attribute :name, "Updated task"
130
+ @task.destroy
131
+
132
+ assert_equal 1, @user.activities.count(:conditions => {:action => "update"})
133
+ assert_equal 1, @user.activities.count
134
+ end
135
+
136
+ def test_create_activities_for_all_actions
137
+ User.activities_for(:tasks) do
138
+ track :create
139
+ track :update
140
+ track :destroy
141
+ end
142
+
143
+ @task = @user.tasks.create(:name => "New task")
144
+ assert_equal 1, @user.activities.count(:conditions => {:action => "create"})
145
+
146
+ @task.update_attribute :name, "Updated task"
147
+ assert_equal 1, @user.activities.count(:conditions => {:action => "update"})
148
+
149
+ @task.destroy
150
+ assert_equal 1, @user.activities.count(:conditions => {:action => "destroy"})
151
+
152
+ assert_equal 3, @user.activities.count
153
+ end
154
+
155
+ def test_create_activity_respecting_the_if_option_using_symbol
156
+ User.activities_for(:projects) do
157
+ track :renamed, :on => :update, :if => :name_changed?
158
+ end
159
+
160
+ @project = @user.projects.create(:name => "New project", :status => "opened")
161
+ @project.update_attribute :name, "Updated project"
162
+
163
+ assert_equal 1, @user.activities.count(:conditions => {:action => "renamed"})
164
+ assert_equal 1, @user.activities.count
165
+ end
166
+
167
+ def test_dont_create_activity_when_if_evaluation_returns_false_symbol
168
+ User.activities_for(:projects) do
169
+ track :renamed, :on => :update, :if => :name_changed?
170
+ end
171
+
172
+ @project = @user.projects.create(:name => "New project", :status => "opened")
173
+ assert_equal 0, Activity.count
174
+
175
+ @project.update_attribute :status, "archived"
176
+ assert_equal 0, Activity.count
177
+ end
178
+
179
+ def test_create_activity_respecting_the_if_option_using_block
180
+ User.activities_for(:projects) do
181
+ track :renamed, :on => :update, :if => proc {|r| r.name_changed?}
182
+ end
183
+
184
+ @project = @user.projects.create(:name => "New project", :status => "opened")
185
+ @project.update_attribute :name, "Updated project"
186
+
187
+ assert_equal 1, @user.activities.count(:conditions => {:action => "renamed"})
188
+ assert_equal 1, @user.activities.count
189
+ end
190
+
191
+ def test_dont_create_activity_when_if_evaluation_returns_false_block
192
+ User.activities_for(:projects) do
193
+ track :renamed, :on => :update, :if => proc {|r| r.name_changed?}
194
+ end
195
+
196
+ @project = @user.projects.create(:name => "New project", :status => "opened")
197
+ assert_equal 0, Activity.count
198
+
199
+ @project.update_attribute :status, "archived"
200
+ assert_equal 0, Activity.count
201
+ end
202
+
203
+ def test_create_activity_respecting_the_unless_option_using_symbol
204
+ User.activities_for(:projects) do
205
+ track :renamed, :on => :update, :unless => :status_changed?
206
+ end
207
+
208
+ @project = @user.projects.create(:name => "New project", :status => "opened")
209
+ @project.update_attribute :name, "Updated project"
210
+ assert_equal 1, @user.activities.count(:conditions => {:action => "renamed"})
211
+ assert_equal 1, @user.activities.count
212
+ end
213
+
214
+ def test_create_activity_respecting_the_unless_option_using_block
215
+ User.activities_for(:projects) do
216
+ track :renamed, :on => :update, :unless => proc {|r| r.status_changed?}
217
+ end
218
+
219
+ @project = @user.projects.create(:name => "New project", :status => "opened")
220
+ @project.update_attribute :name, "Updated project"
221
+ assert_equal 1, @user.activities.count(:conditions => {:action => "renamed"})
222
+ assert_equal 1, @user.activities.count
223
+ end
224
+
225
+ def test_dont_create_activity_when_unless_evaluation_returns_false_block
226
+ User.activities_for(:projects) do
227
+ track :renamed, :on => :update, :unless => proc {|r| r.status_changed?}
228
+ end
229
+
230
+ @project = @user.projects.create(:name => "New project", :status => "opened")
231
+ @project.update_attributes :status => "archived", :name => "Updated project"
232
+ assert_equal 0, Activity.count
233
+ end
234
+
235
+ def test_dont_create_activity_when_unless_evaluation_returns_false_symbol
236
+ User.activities_for(:projects) do
237
+ track :renamed, :on => :update, :unless => :status_changed?
238
+ end
239
+
240
+ @project = @user.projects.create(:name => "New project", :status => "opened")
241
+ @project.update_attributes :status => "archived", :name => "Updated project"
242
+ assert_equal 0, Activity.count
243
+ end
244
+ end
@@ -0,0 +1,21 @@
1
+ class Task < ActiveRecord::Base
2
+ belongs_to :user
3
+ belongs_to :project
4
+ end
5
+
6
+ class Project < ActiveRecord::Base
7
+ belongs_to :user
8
+ has_many :milestones
9
+ has_many :tasks
10
+ end
11
+
12
+ class Milestone < ActiveRecord::Base
13
+ belongs_to :user
14
+ belongs_to :project
15
+ end
16
+
17
+ class User < ActiveRecord::Base
18
+ has_many :milestones
19
+ has_many :tasks
20
+ has_many :projects
21
+ end
@@ -0,0 +1,28 @@
1
+ ActiveRecord::Schema.define(:version => 0) do
2
+ create_table :users do |t|
3
+ t.string :login
4
+ end
5
+
6
+ create_table :tasks do |t|
7
+ t.string :name
8
+ t.references :user, :project
9
+ end
10
+
11
+ create_table :milestones do |t|
12
+ t.string :name
13
+ t.references :user, :project
14
+ end
15
+
16
+ create_table :projects do |t|
17
+ t.string :name, :status
18
+ t.references :user
19
+ end
20
+
21
+ create_table :activities do |t|
22
+ t.references :tracker, :polymorphic => true, :null => false
23
+ t.references :trackable, :polymorphic => true, :null => false
24
+ t.string :action, :null => false
25
+ t.text :data, :null => true
26
+ t.timestamps
27
+ end
28
+ end
@@ -0,0 +1,11 @@
1
+ require "rubygems"
2
+ gem "test-unit"
3
+ require "test/unit"
4
+ require "active_record"
5
+ require "mocha"
6
+
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
8
+ load "schema.rb"
9
+
10
+ require "activities"
11
+ require "resources/models"
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: activities
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Nando Vieira
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-13 00:00:00 -03:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: activerecord
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description:
33
+ email: fnando.vieira@gmail.com
34
+ executables: []
35
+
36
+ extensions: []
37
+
38
+ extra_rdoc_files:
39
+ - README.rdoc
40
+ files:
41
+ - README.rdoc
42
+ - Rakefile
43
+ - lib/activities.rb
44
+ - lib/activities/active_record.rb
45
+ - lib/activities/active_record/class_methods.rb
46
+ - lib/activities/active_record/instance_methods.rb
47
+ - lib/activities/activity.rb
48
+ - lib/activities/dsl.rb
49
+ - lib/activities/helper.rb
50
+ - lib/activities/version.rb
51
+ - test/activities/active_record_test.rb
52
+ - test/resources/models.rb
53
+ - test/schema.rb
54
+ - test/test_helper.rb
55
+ has_rdoc: true
56
+ homepage: http://github.com/fnando/activities
57
+ licenses: []
58
+
59
+ post_install_message:
60
+ rdoc_options:
61
+ - --charset=UTF-8
62
+ require_paths:
63
+ - lib
64
+ required_ruby_version: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ segments:
69
+ - 0
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ segments:
76
+ - 0
77
+ version: "0"
78
+ requirements: []
79
+
80
+ rubyforge_project:
81
+ rubygems_version: 1.3.6
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: A framework for aggregating social activity.
85
+ test_files:
86
+ - test/activities/active_record_test.rb
87
+ - test/resources/models.rb
88
+ - test/schema.rb
89
+ - test/test_helper.rb