acts_as_mongo_rateable 0.2.0

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/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 [name of plugin creator]
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/Manifest ADDED
@@ -0,0 +1,13 @@
1
+ MIT-LICENSE
2
+ README.markdown
3
+ Rakefile
4
+ install.rb
5
+ lib/acts_as_mongo_rateable/acts_as_mongo_rateable.rb
6
+ lib/acts_as_mongo_rateable/app/models/rating.rb
7
+ lib/mongo_rateable.rb
8
+ rails/init.rb
9
+ tasks/mongo_rateable_tasks.rake
10
+ test/mongo_rateable_test.rb
11
+ test/test_helper.rb
12
+ uninstall.rb
13
+ Manifest
data/README.markdown ADDED
@@ -0,0 +1,88 @@
1
+ ActsAsMongoRateable (with weights!)
2
+ ===================================
3
+
4
+ Inspired by the old Rails+AR standby "acts_as_rateable," this rating plugin works with MongoDB+MongoMapper
5
+ and has weighted ratings, as well as bayesian and straight averages, and some friendly class-level helpers.
6
+
7
+ Intends to be super-performant by taking advantage of the benefits of document-driven db denormalization.
8
+
9
+ Requirements
10
+ ------------
11
+
12
+ - MongoDB
13
+ - MongoMapper gem
14
+ - Expects you to have a User model that includes MongoMapper::Document
15
+
16
+ Installation
17
+ ------------
18
+
19
+ Install the plugin:
20
+
21
+ ./script/plugin install git://github.com/mepatterson/acts_as_mongo_rateable.git
22
+
23
+ Add the following 2 lines to the Model class that you want to make rateable:
24
+
25
+ include ActsAsMongoRateable
26
+ RATING_RANGE = (1..5)
27
+
28
+ Obviously, change the rating range if you want to rate on a 10-star system or a 14-star or whatever.
29
+
30
+ Usage
31
+ -----
32
+
33
+ class User
34
+ include MongoMapper::Document
35
+ end
36
+
37
+ class Widget
38
+ include ActsAsMongoRateable
39
+ RATING_RANGE = (1..5)
40
+ include MongoMapper::Document
41
+ end
42
+
43
+ widget = Widget.first
44
+
45
+ To rate it:
46
+
47
+ widget.rate(score, user, weight)
48
+
49
+ - score must be an Integer within your RATING_RANGE
50
+ - user is the User who is rating this widget
51
+ - weight is optional; defaults to 1)
52
+
53
+ Now try all these fun methods:
54
+
55
+ widget.average_rating
56
+
57
+ widget.bayesian_rating
58
+
59
+ widget.rating_stats
60
+
61
+ And some useful class methods:
62
+
63
+ Widget.highest_rated(how_many)
64
+
65
+ Widget.most_rated(how_many)
66
+
67
+ Widget.most_rated_by_authorities(how_many)
68
+
69
+ Widget.highest_bayesian_rated(how_many)
70
+
71
+ ('how_many' is a limit and is optional. i.e. Do you want a highest_rated list of 5, 10, 15 widgets?
72
+ Defaults to just 1 if you don't pass any argument.)
73
+
74
+ Future
75
+ ------
76
+ - Tests (I have tests in the project I cut this from, but they need to be extracted out and I'm lazy)
77
+ - More helper methods
78
+ - Performance improvements as I come across the need
79
+ - Investigate using map/reduce to improve the efficiency of the bayesian calc (?)
80
+
81
+ Thanks To...
82
+ ------------
83
+ - John Nunemaker and the rest of the folks on the MongoMapper Google Group
84
+ - The MongoDB peoples and the MongoDB Google Group
85
+ - juixe for the original acts_as_rateable plugin for ActiveRecord
86
+ - sunlightlabs 'datacatalog-api', from which I borrowed the ratings_stats hash methodology
87
+
88
+ Copyright (c) 2009 [M. E. Patterson], released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,35 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+ require 'echoe'
4
+ require 'rake/testtask'
5
+ require 'rake/rdoctask'
6
+
7
+ desc 'Default: run unit tests.'
8
+ task :default => :test
9
+
10
+ desc 'Test the mongo_rateable plugin.'
11
+ Rake::TestTask.new(:test) do |t|
12
+ t.libs << 'lib'
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = true
16
+ end
17
+
18
+ desc 'Generate documentation for the mongo_rateable plugin.'
19
+ Rake::RDocTask.new(:rdoc) do |rdoc|
20
+ rdoc.rdoc_dir = 'rdoc'
21
+ rdoc.title = 'MongoRateable'
22
+ rdoc.options << '--line-numbers' << '--inline-source'
23
+ rdoc.rdoc_files.include('README')
24
+ rdoc.rdoc_files.include('lib/**/*.rb')
25
+ end
26
+
27
+
28
+ Echoe.new('acts_as_mongo_rateable', '0.2.0') do |p|
29
+ p.description = "A ratings system for Rails apps using MongoDB, with bayesian and straight averages, and weighting."
30
+ p.url = "http://github.com/mepatterson/acts_as_mongo_rateable"
31
+ p.author = "M. E. Patterson"
32
+ p.email = "madraziel @nospam@ gmail.com"
33
+ p.ignore_pattern = ["tmp/*", "script/*"]
34
+ p.development_dependencies = []
35
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{acts_as_mongo_rateable}
5
+ s.version = "0.2.0"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["M. E. Patterson"]
9
+ s.cert_chain = ["/Users/mattp/gem-public_cert.pem"]
10
+ s.date = %q{2010-06-04}
11
+ s.description = %q{A ratings system for Rails apps using MongoDB, with bayesian and straight averages, and weighting.}
12
+ s.email = %q{madraziel @nospam@ gmail.com}
13
+ s.extra_rdoc_files = ["README.markdown", "lib/acts_as_mongo_rateable/acts_as_mongo_rateable.rb", "lib/acts_as_mongo_rateable/app/models/rating.rb", "lib/mongo_rateable.rb", "tasks/mongo_rateable_tasks.rake"]
14
+ s.files = ["MIT-LICENSE", "README.markdown", "Rakefile", "install.rb", "lib/acts_as_mongo_rateable/acts_as_mongo_rateable.rb", "lib/acts_as_mongo_rateable/app/models/rating.rb", "lib/mongo_rateable.rb", "rails/init.rb", "tasks/mongo_rateable_tasks.rake", "test/mongo_rateable_test.rb", "test/test_helper.rb", "uninstall.rb", "Manifest", "acts_as_mongo_rateable.gemspec"]
15
+ s.homepage = %q{http://github.com/mepatterson/acts_as_mongo_rateable}
16
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Acts_as_mongo_rateable", "--main", "README.markdown"]
17
+ s.require_paths = ["lib"]
18
+ s.rubyforge_project = %q{acts_as_mongo_rateable}
19
+ s.rubygems_version = %q{1.3.7}
20
+ s.signing_key = %q{/Users/mattp/gem-private_key.pem}
21
+ s.summary = %q{A ratings system for Rails apps using MongoDB, with bayesian and straight averages, and weighting.}
22
+ s.test_files = ["test/mongo_rateable_test.rb", "test/test_helper.rb"]
23
+
24
+ if s.respond_to? :specification_version then
25
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
26
+ s.specification_version = 3
27
+
28
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
29
+ else
30
+ end
31
+ else
32
+ end
33
+ end
data/install.rb ADDED
@@ -0,0 +1 @@
1
+ # Install hook code here
@@ -0,0 +1,109 @@
1
+ module ActsAsMongoRateable
2
+
3
+ module ClassMethods
4
+ def highest_rated(limit=1)
5
+ all({:order => "rating_stats.average DESC", :limit => limit})
6
+ end
7
+
8
+ def most_rated(limit=1)
9
+ all({:order => "rating_stats.count DESC", :limit => limit})
10
+ end
11
+
12
+ def most_rated_by_authorities(limit=1)
13
+ all({:order => "rating_stats.sum_of_weights DESC", :limit => limit})
14
+ end
15
+
16
+ # TO DO this is awful, awful, awful! make it faster using map/reduce
17
+ def highest_bayesian_rated(limit=1)
18
+ stats = all({:select => 'id, rating_stats'})
19
+ all.sort_by do |doc|
20
+ rating = doc.bayesian_rating(stats)
21
+ doc.rating_stats['bayesian_rating'] = rating
22
+ rating
23
+ end.reverse[0,limit]
24
+ end
25
+
26
+ end
27
+
28
+ module InstanceMethods
29
+
30
+ def delete_all_ratings
31
+ ratings.delete_all
32
+ end
33
+
34
+ def average_rating
35
+ rating_stats['average']
36
+ end
37
+
38
+ def bayesian_rating(stats=nil)
39
+ return 0 if rating_stats['count'] == 0
40
+ stats ||= self.class.all({:select => 'id, rating_stats'})
41
+ system_counts = stats.map{ |p| [ p.id.to_s, p.rating_stats['count'] ] }
42
+ avg_rating = stats.map{|p| p.rating_stats['average'] || 0 }.sum / stats.size.to_f
43
+ avg_num_votes = system_counts.inject(0){|sum, r| sum += r.to_a.flatten[1] } / system_counts.size.to_f
44
+ my_rating = rating_stats['average'] || 0
45
+ my_count = rating_stats['count']
46
+ ( (avg_num_votes * avg_rating) + (my_count * my_rating) ) / (avg_num_votes + my_count)
47
+ end
48
+
49
+ def delete_ratings_by_user(user)
50
+ return false unless user
51
+ return 0 if ratings.blank?
52
+ ratings.delete_all(:user_id => user.id.to_s)
53
+ self.reload
54
+ end
55
+
56
+ def rate(value, user = nil, weight = 1)
57
+ delete_ratings_by_user(user)
58
+ validate_rating!(value)
59
+ r = Rating.new({
60
+ :value => value,
61
+ :user_id => user.id,
62
+ :rateable_id => self.id,
63
+ :rateable_class => self.class.to_s,
64
+ :weight => weight
65
+ })
66
+ self.ratings << r
67
+ self.reload
68
+ r
69
+ end
70
+
71
+ # returns the Rating object found if user has rated this project, else returns nil
72
+ def rated_by_user?(user)
73
+ return false unless user
74
+ ratings.detect{ |r| r.user_id == user.id}
75
+ end
76
+
77
+ protected
78
+
79
+ def validate_rating!(value)
80
+ if (range = self.class::RATING_RANGE) and !range.include?(value.to_i)
81
+ raise ArgumentError, "Rating not in range #{range}. Rating provided was #{value}."
82
+ end
83
+ end
84
+
85
+ end
86
+
87
+ def self.included(receiver)
88
+ receiver.class_eval do
89
+ many :ratings, :foreign_key => 'rateable_id', :dependent => :destroy
90
+ key :rating_stats, Hash, :default => {
91
+ :total => 0,
92
+ :count => 0,
93
+ :sum_of_weights => 0,
94
+ :average => nil
95
+ }
96
+ end
97
+ receiver.extend ClassMethods
98
+ receiver.send :include, InstanceMethods
99
+ end
100
+
101
+
102
+ end
103
+
104
+ %w{ models observers }.each do |dir|
105
+ path = File.join(File.dirname(__FILE__), 'app', dir)
106
+ $LOAD_PATH << path
107
+ ActiveSupport::Dependencies.load_paths << path
108
+ ActiveSupport::Dependencies.load_once_paths.delete(path)
109
+ end
@@ -0,0 +1,72 @@
1
+ class Rating
2
+ include MongoMapper::Document
3
+
4
+ key :user_id, ObjectId, :required => true
5
+ key :rateable_id, ObjectId, :required => true
6
+ key :rateable_class, String, :required => true
7
+ key :value, Integer, :required => true
8
+ key :previous_value, Integer, :default => 0
9
+ key :weight, Integer, :default => 1
10
+ timestamps!
11
+
12
+ ensure_index :user_id
13
+ ensure_index :rateable_id
14
+ ensure_index :rateable_class
15
+ ensure_index :created_at
16
+
17
+ belongs_to :user
18
+
19
+ after_create :set_rating_stats
20
+ after_update :update_rating_stats
21
+ before_update :set_previous_value
22
+ after_destroy :reduce_rating_stats
23
+
24
+ def set_rating_stats
25
+ doc = find_rated_document!
26
+ count = (doc.rating_stats[:count] += 1)
27
+ total = (doc.rating_stats[:total] += ( value * weight ))
28
+ sow = (doc.rating_stats[:sum_of_weights] += weight)
29
+ doc.rating_stats[:average] = total.to_f / sow
30
+ doc.save!
31
+ end
32
+
33
+ def set_previous_value
34
+ rating_from_db = Rating.find_by_id(id)
35
+ previous_value = (rating_from_db.value * weight) if rating_from_db
36
+ end
37
+
38
+ def update_rating_stats
39
+ doc = find_rated_document!
40
+ value_delta = (value * weight) - (previous_value * weight)
41
+ total = (doc.rating_stats[:total] += value_delta)
42
+ count = doc.rating_stats[:count]
43
+ doc.rating_stats[:average] = total.to_f / count
44
+ doc.save
45
+ end
46
+
47
+ def reduce_rating_stats
48
+ doc = find_rated_document
49
+ return if doc.nil?
50
+ count = (doc.rating_stats[:count] -= 1)
51
+ doc.rating_stats[:total] -= (value * weight)
52
+ doc.rating_stats[:sum_of_weights] -= weight
53
+ doc.rating_stats[:average] = nil if count == 0
54
+ doc.save
55
+ end
56
+
57
+
58
+ # == Various Instance Methods
59
+ def find_rated_document
60
+ klass = rateable_class.constantize
61
+ klass.find(rateable_id.to_s)
62
+ end
63
+
64
+ def find_rated_document!
65
+ doc = find_rated_document
66
+ raise "Associated document not found" if doc.nil?
67
+ doc
68
+ end
69
+
70
+ end
71
+
72
+
@@ -0,0 +1 @@
1
+ require 'acts_as_mongo_rateable/acts_as_mongo_rateable'
data/rails/init.rb ADDED
@@ -0,0 +1,2 @@
1
+ require File.dirname(__FILE__) + '/../lib/mongo_rateable.rb'
2
+
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :mongo_rateable do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,171 @@
1
+ require File.dirname(__FILE__) + '/test_helper.rb'
2
+
3
+ class MongoRateableTest < ActiveSupport::TestCase
4
+
5
+ def create_user(name)
6
+ u = User.create({:name => name})
7
+ puts u.errors unless u.valid?
8
+ u
9
+ end
10
+
11
+ def load_multiple_raters
12
+ @m_rater_1 = create_user "m_rater_1"
13
+ @m_rater_2 = create_user "m_rater_2"
14
+ @m_rater_3 = create_user "m_rater_3"
15
+ [@m_rater_1, @m_rater_2, @m_rater_3]
16
+ end
17
+
18
+ def load_multiple_widgets
19
+ @widget = @owner.widgets.create({:name => "Test Widget"})
20
+ @widget_2 = @owner.widgets.create({:name => "Test Widget 2"})
21
+ @widget_3 = @owner.widgets.create({:name => "Test Widget 3"})
22
+ [@widget, @widget_2, @widget_3]
23
+ end
24
+
25
+ def load_multiple_dongles
26
+ @dongle = @owner.dongles.create({:name => "Test dongle"})
27
+ @dongle_2 = @owner.dongles.create({:name => "Test dongle 2"})
28
+ @dongle_3 = @owner.dongles.create({:name => "Test dongle 3"})
29
+ [@dongle, @dongle_2, @dongle_3]
30
+ end
31
+
32
+ def rate_this_many_times(obj, count, authority=1)
33
+ x = 0
34
+ count.times do
35
+ x += 1
36
+ rater = create_user "fake_rater_#{x}"
37
+ obj.rate(4, rater, authority)
38
+ end
39
+ end
40
+
41
+ def load_and_randomly_rate_multiple_widgets
42
+ raters = load_multiple_raters
43
+ widgets = load_multiple_widgets
44
+ widgets.each do |w|
45
+ raters.each {|r| w.rate(rand(5)+1, r, rand(3)+1) }
46
+ end
47
+ end
48
+
49
+ def load_and_randomly_rate_multiple_dongles
50
+ raters = load_multiple_raters
51
+ dongles = load_multiple_dongles
52
+ dongles.each do |d|
53
+ raters.each {|r| d.rate(rand(5)+1, r, rand(3)+1) }
54
+ end
55
+ end
56
+
57
+ def multi_rate(obj)
58
+ load_multiple_raters
59
+ obj.rate(4, @m_rater_1, 1)
60
+ obj.rate(2, @m_rater_2, 3)
61
+ obj.rate(5, @m_rater_3, 5)
62
+ end
63
+
64
+ def multi_rate_many_widgets
65
+ load_multiple_widgets
66
+ raters = load_multiple_raters
67
+ raters.each do |r|
68
+ @widget.rate(5, r, 2)
69
+ @widget_2.rate(1, r, 2)
70
+ @widget_3.rate(3, r, 2)
71
+ end
72
+ end
73
+
74
+ def setup
75
+ @owner = create_user 'owner'
76
+ @rater = create_user 'rater'
77
+ @widget = @owner.widgets.create({:name => "Test Widget"})
78
+ end
79
+
80
+ test "single rating on a widget produces the correct rating stats" do
81
+ @widget.rate(3, @rater, 2)
82
+ expected_stats = {"total" => 6, "count" => 1, "average" => 3.to_f, "sum_of_weights" => 2}
83
+ %w( total count average sum_of_weights).each do |method|
84
+ assert_equal expected_stats[method], @widget.rating_stats[method]
85
+ end
86
+ end
87
+
88
+ test "multiple ratings on a widget produce the correct rating stats" do
89
+ multi_rate(@widget)
90
+ expected_stats = {"total" => 35, "count" => 3, "average" => 3.88888888888889, "sum_of_weights" => 9}
91
+ %w( total count sum_of_weights).each do |method|
92
+ assert_equal expected_stats[method], @widget.rating_stats[method]
93
+ end
94
+ # doing average seperately, since we don't need to test the whole long float
95
+ assert_equal sprintf('%.2f',expected_stats['average']), sprintf('%.2f',@widget.rating_stats['average'])
96
+ end
97
+
98
+ test "deleting all ratings for a specific widget works" do
99
+ load_and_randomly_rate_multiple_widgets
100
+ assert_equal 3, @widget.ratings.count
101
+ assert_equal 9, Rating.count
102
+ @widget.delete_all_ratings
103
+ assert_equal 0, @widget.ratings.count
104
+ assert_equal 6, Rating.count
105
+ end
106
+
107
+ test "deleting all ratings for a particular object doesn't delete ratings for other object" do
108
+ load_and_randomly_rate_multiple_widgets
109
+ load_and_randomly_rate_multiple_dongles
110
+ assert_equal 18, Rating.count
111
+ @widget.delete_all_ratings
112
+ assert_equal 0, @widget.ratings.count
113
+ assert_equal 3, @dongle.ratings.count
114
+ end
115
+
116
+ test "rated_by_user? works" do
117
+ multi_rate(@widget)
118
+ assert @widget.rated_by_user?(@m_rater_1)
119
+ end
120
+
121
+ test "delete by user only deletes ratings by that user for that object" do
122
+ @dongle = @owner.dongles.create({:name => "Test dongle"})
123
+ multi_rate(@widget)
124
+ widget_rater = @m_rater_1
125
+ multi_rate(@dongle)
126
+ assert_equal 6, Rating.count
127
+ assert_equal 3, @widget.ratings.count
128
+ assert @widget.rated_by_user?(widget_rater)
129
+ @widget.delete_ratings_by_user(widget_rater)
130
+ assert ! @widget.rated_by_user?(widget_rater)
131
+ assert_equal 2, @widget.ratings.count
132
+ assert_equal 5, Rating.count
133
+ end
134
+
135
+ test "bayesian_rating returns correct number" do
136
+ multi_rate_many_widgets
137
+ assert_equal sprintf('%.2f',3.82), sprintf('%.2f',@widget.bayesian_rating)
138
+ assert_equal sprintf('%.2f',1.54), sprintf('%.2f',@widget_2.bayesian_rating)
139
+ assert_equal sprintf('%.2f',2.68), sprintf('%.2f',@widget_3.bayesian_rating)
140
+ end
141
+
142
+ test "bayesian_rating for one class of objects not corrupted by other ratings for other classes" do
143
+ multi_rate_many_widgets
144
+ load_and_randomly_rate_multiple_dongles
145
+ assert_equal sprintf('%.2f',3.82), sprintf('%.2f',@widget.bayesian_rating)
146
+ assert_equal sprintf('%.2f',1.54), sprintf('%.2f',@widget_2.bayesian_rating)
147
+ assert_equal sprintf('%.2f',2.68), sprintf('%.2f',@widget_3.bayesian_rating)
148
+ end
149
+
150
+ test "highest_rated returns correct widgets in order" do
151
+ multi_rate_many_widgets
152
+ assert_equal [@widget, @widget_3, @widget_2], Widget.highest_rated(3)
153
+ end
154
+
155
+ test "most_rated returns correct widgets in order" do
156
+ load_multiple_widgets
157
+ rate_this_many_times(@widget, 6)
158
+ rate_this_many_times(@widget_2, 1)
159
+ rate_this_many_times(@widget_3, 3)
160
+ assert_equal [@widget, @widget_3, @widget_2], Widget.most_rated(3)
161
+ end
162
+
163
+ test "most_rated_by_authorities returns correct widgets in order" do
164
+ load_multiple_widgets
165
+ rate_this_many_times(@widget, 6, 2)
166
+ rate_this_many_times(@widget_2, 1, 5)
167
+ rate_this_many_times(@widget_3, 3, 1)
168
+ assert_equal [@widget, @widget_2, @widget_3], Widget.most_rated_by_authorities(3)
169
+ end
170
+
171
+ end
@@ -0,0 +1,58 @@
1
+ require 'rubygems'
2
+ require 'active_support'
3
+ require 'active_support/test_case'
4
+
5
+ ENV['RAILS_ENV'] = 'test'
6
+ ENV['RAILS_ROOT'] ||= File.dirname(__FILE__) + '/../../../..'
7
+
8
+ require 'test/unit'
9
+ require File.expand_path(File.join(ENV['RAILS_ROOT'], 'config/environment.rb'))
10
+
11
+ class ActiveSupport::TestCase
12
+ # Drop all columns after each test case.
13
+ def teardown
14
+ MongoMapper.database.collections.each do |coll|
15
+ coll.drop
16
+ end
17
+ end
18
+
19
+ # Make sure that each test case has a teardown
20
+ # method to clear the db after each test.
21
+ def inherited(base)
22
+ base.define_method teardown do
23
+ super
24
+ end
25
+ end
26
+ end
27
+
28
+ # kinda weird, but we have to do this so we can ignore the app's User class and use our own for testing
29
+ Object.send(:remove_const, :User) if Object.const_defined?(:User)
30
+
31
+ class User
32
+ include MongoMapper::Document
33
+ key :name, String
34
+ has_many :widgets
35
+ has_many :dongles
36
+ end
37
+
38
+ class Widget
39
+ include MongoMapper::Document
40
+ include ActsAsMongoRateable
41
+ RATING_RANGE = (1..5)
42
+
43
+ belongs_to :user
44
+
45
+ key :user_id, ObjectId
46
+ key :name, String
47
+ end
48
+
49
+ class Dongle
50
+ include MongoMapper::Document
51
+ include ActsAsMongoRateable
52
+ RATING_RANGE = (1..5)
53
+
54
+ belongs_to :user
55
+
56
+ key :user_id, ObjectId
57
+ key :name, String
58
+ end
data/uninstall.rb ADDED
@@ -0,0 +1 @@
1
+ # Uninstall hook code here
data.tar.gz.sig ADDED
@@ -0,0 +1,3 @@
1
+ �Zw{��x�s;�s�wVa�ƌPoP5T@��}R`wm_;P���z�����ْM������3��NU�EQhWN�t=�w��)�����b�
2
+
3
+ Q '������d�� �I �#�u����i*�I~d.�fDY�6�Q��S��u�� ])ȬV��^�R�rI��-�h�\G^������3�_@�� ����{��*�}~����Z�N��W�x�\�5�M����!
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: acts_as_mongo_rateable
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 2
9
+ - 0
10
+ version: 0.2.0
11
+ platform: ruby
12
+ authors:
13
+ - M. E. Patterson
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain:
17
+ - |
18
+ -----BEGIN CERTIFICATE-----
19
+ MIIDNDCCAhygAwIBAgIBADANBgkqhkiG9w0BAQUFADBAMRIwEAYDVQQDDAltYWRy
20
+ YXppZWwxFTATBgoJkiaJk/IsZAEZFgVnbWFpbDETMBEGCgmSJomT8ixkARkWA2Nv
21
+ bTAeFw0xMDA2MDUwNDUxMThaFw0xMTA2MDUwNDUxMThaMEAxEjAQBgNVBAMMCW1h
22
+ ZHJhemllbDEVMBMGCgmSJomT8ixkARkWBWdtYWlsMRMwEQYKCZImiZPyLGQBGRYD
23
+ Y29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2YYU8nBcWrz3Gls3
24
+ B4tKCLGU/v11vuLeDU51r0/mUL/ev4GAZOrlBRaIn4U3J53W4Wa3fHGNqDyB7dt4
25
+ eJS2a//eBv5MXtDxS0kuOeLen4sJiACN7WzoX/WaMiCdeLFebRFr6zDKtYMQZ1lM
26
+ x+DWXbFLBuWfihZ8TapkBBG8Yuw2J+OcJla7t0IR3KHJSpOe0e9D/rHydly2v7kH
27
+ 6naqt5n4jtpTXrmgLeGUQeVR60BJrHIbHXjgUCkPz3b/prreaRl/a4Cufv0cTPMD
28
+ BFSOlmK6AKLii9gdaZMnLbF7b1Jc3rAcYNAsLHoUBGoq0Top8CTC732YrNZ7NmFp
29
+ /Jn0nQIDAQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQU
30
+ drmilB9ksqsW9hFPopqQEhcFdh8wDQYJKoZIhvcNAQEFBQADggEBAHPZLmxi4DYD
31
+ qdSsUv4oTlWoK5nCbEpnJRpJZXn1rn30Zaoc5v7kQfVwz/x/4uZmLdvfysZmuvKZ
32
+ GTMlYv/qSylO0SqbZeKhvsehQ+ENQdTon10zPtVvvnxiUE/As79eRmmxNGypJnwy
33
+ WZH2x1I+Hd25mRbt1UspT2vmuEwTgzkmxGHnl7cmiO4BYXlzHHk8KRSEdIDZUm5T
34
+ B+pavzaE15aDJrbpy+/awgxQEZb7O/mgzkFoTKlgV4VyDWSDjtU+aEI1sJk0DiSs
35
+ Zm3n8B2/BZXgeEcymjLxZGMrvkax12f02NF2l+C8f0/DzS+jlVsewUzux0WmYCR5
36
+ 47YifzlLjIM=
37
+ -----END CERTIFICATE-----
38
+
39
+ date: 2010-06-04 00:00:00 -05:00
40
+ default_executable:
41
+ dependencies: []
42
+
43
+ description: A ratings system for Rails apps using MongoDB, with bayesian and straight averages, and weighting.
44
+ email: madraziel @nospam@ gmail.com
45
+ executables: []
46
+
47
+ extensions: []
48
+
49
+ extra_rdoc_files:
50
+ - README.markdown
51
+ - lib/acts_as_mongo_rateable/acts_as_mongo_rateable.rb
52
+ - lib/acts_as_mongo_rateable/app/models/rating.rb
53
+ - lib/mongo_rateable.rb
54
+ - tasks/mongo_rateable_tasks.rake
55
+ files:
56
+ - MIT-LICENSE
57
+ - README.markdown
58
+ - Rakefile
59
+ - install.rb
60
+ - lib/acts_as_mongo_rateable/acts_as_mongo_rateable.rb
61
+ - lib/acts_as_mongo_rateable/app/models/rating.rb
62
+ - lib/mongo_rateable.rb
63
+ - rails/init.rb
64
+ - tasks/mongo_rateable_tasks.rake
65
+ - test/mongo_rateable_test.rb
66
+ - test/test_helper.rb
67
+ - uninstall.rb
68
+ - Manifest
69
+ - acts_as_mongo_rateable.gemspec
70
+ has_rdoc: true
71
+ homepage: http://github.com/mepatterson/acts_as_mongo_rateable
72
+ licenses: []
73
+
74
+ post_install_message:
75
+ rdoc_options:
76
+ - --line-numbers
77
+ - --inline-source
78
+ - --title
79
+ - Acts_as_mongo_rateable
80
+ - --main
81
+ - README.markdown
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 11
99
+ segments:
100
+ - 1
101
+ - 2
102
+ version: "1.2"
103
+ requirements: []
104
+
105
+ rubyforge_project: acts_as_mongo_rateable
106
+ rubygems_version: 1.3.7
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: A ratings system for Rails apps using MongoDB, with bayesian and straight averages, and weighting.
110
+ test_files:
111
+ - test/mongo_rateable_test.rb
112
+ - test/test_helper.rb
metadata.gz.sig ADDED
Binary file