mongo_followable 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/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in mongo_followable.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Jie Fan
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.rdoc ADDED
@@ -0,0 +1,115 @@
1
+ = mongo_followable
2
+
3
+ Now works for both Mongoid and Mongo_Mapper!
4
+
5
+ == Installation
6
+
7
+ In console:
8
+ gem install mongo_followable
9
+ or in Gemfile:
10
+ gem 'mongo_followable', "~> 0.2.0"
11
+
12
+ == Usage
13
+
14
+ To make model followable you need to include Mongo::Followable into your document;Meanwhile, you also need to include Mongo::Follower in your follower model:
15
+ class User
16
+ include Mongo::Document
17
+ include Mongo::Followable
18
+ include Mongo::Follower
19
+ end
20
+
21
+ class Group
22
+ include Mongo::Document
23
+ include Mongo::Followable
24
+ end
25
+
26
+ Now you can set authorization:
27
+ current_user.set_authorization('user', 'game') # now current_user cannot follow User and Game model
28
+ current_user.unset_authorization('User', 'Game')
29
+
30
+ And then you can follow a model:
31
+
32
+ @group = Group.new
33
+ @group.save
34
+
35
+ current_user.follow(@group)
36
+ current_user.unfollow(@group)
37
+
38
+ You can also judge whether a model is a follower of another model or a model is a followee of another model:
39
+
40
+ current_user.follower_of?(@group)
41
+ current_user.followee_of?(@group)
42
+
43
+ Moreover, it's easy to get a model's follower/followee count:
44
+
45
+ current_user.followers_count
46
+ current_user.followees_count
47
+
48
+ Of course, you can get a list of followers/followees:
49
+
50
+ User.followers_of(@group)
51
+ User.followees_of(@group)
52
+
53
+ @group.all_followers
54
+ @user.all_followees
55
+
56
+ Getting a model's followers/followees by type is also possible:
57
+
58
+ @group.followers_by_type("user")
59
+ @user.followees_by_type("group")
60
+
61
+ And their count:
62
+
63
+ @group.followers_by_type("user")
64
+ @group.followers_count_by_type("user")
65
+ @user.followees_by_type("group")
66
+ @user.followees_count_by_type("group")
67
+
68
+ You can also get a model's follow/followed history:
69
+
70
+ @user.ever_follow
71
+ @group.ever_followed
72
+
73
+ Another feature is to get a list of models which has the most followers/followees:
74
+
75
+ User.with_max_followees
76
+ User.with_min_followees
77
+ User.with_max_followees_by_type('group')
78
+ User.with_min_followees_by_type('group')
79
+ Group.with_max_followers
80
+ Group.with_min_followers
81
+ Group.with_max_followers_by_type('user')
82
+ Group.with_min_followers_by_type('user')
83
+
84
+ Now you can tell if two models have some common followers/followees by following methods:
85
+
86
+ @user.common_followees?(@another_user)
87
+ @user.common_followers?(@group)
88
+
89
+ And see what the common followers/followees are:
90
+
91
+ @user.common_followees_with(@another_user)
92
+ @user.common_followers_with(@group)
93
+
94
+ * Any bug or issue, please send me an email: ustc.flyingfox@gmail.com
95
+
96
+ == TODO
97
+
98
+ * inter-models followable #FINISHED#
99
+ * divide into two parts: followable(being followed) and follower(following others) #FINISHED#
100
+ * following history/followed history #FINISHED#
101
+ * most/least followed/following #FINISHED
102
+ * add authorization to followable models #FINISHED#
103
+ * common followers/followees #FINISHED#
104
+ * add support for mongo_mapper in next version #FINISHED#
105
+
106
+ !!If you have any advice, plese do not hesitate to tell me!!
107
+
108
+ == Thanks
109
+
110
+ Thanks the author(s) of acts_as_followable, you can find this gem here[https://github.com/xpepermint/acts_as_followable]
111
+ Thanks the author(s) of voteable_mongo, you can find this gem here[https://github.com/vinova/voteable_mongo]
112
+
113
+ == Copyright
114
+
115
+ Copyright (c) Jie Fan. See LICENSE.txt for further details.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,19 @@
1
+ class Follow
2
+ if defined?(Mongoid)
3
+ include Mongoid::Document
4
+
5
+ field :f_type, :type => String
6
+ field :f_id, :type => String
7
+ elsif defined?(MongoMapper)
8
+ include MongoMapper::Document
9
+
10
+ key :f_type, :type => String
11
+ key :f_id, :type => String
12
+ end
13
+
14
+ belongs_to :followable, :polymorphic => true
15
+ belongs_to :following, :polymorphic => true
16
+
17
+ scope :by_type, lambda { |type| where(:f_type => type.capitalize) }
18
+ scope :by_model, lambda { |model| where(:f_id => model.id.to_s).by_type(model.class.name) }
19
+ end
@@ -0,0 +1,185 @@
1
+ module Mongo
2
+ module Followable
3
+ extend ActiveSupport::Concern
4
+
5
+ included do |base|
6
+ if defined?(Mongoid)
7
+ base.field :cannot_followed, :type => Array, :default => []
8
+ base.field :followed_history, :type => Array, :default => []
9
+ base.has_many :followers, :class_name => "Follow", :as => :followable, :dependent => :destroy
10
+ elsif defined?(MongoMapper)
11
+ base.key :cannot_followed, :type => Array, :default => []
12
+ base.key :followed_history, :type => Array, :default => []
13
+ base.many :followers, :class_name => "Follow", :as => :followable, :dependent => :destroy
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ # get certain model's followees of this type
20
+ #
21
+ # Example:
22
+ # >> @jim = User.new
23
+ # >> @ruby = Group.new
24
+ # >> @jim.save
25
+ # >> @ruby.save
26
+ #
27
+ # >> @jim.follow(@ruby)
28
+ # >> User.followees_of(@jim)
29
+ # => [@ruby]
30
+ #
31
+ # Arguments:
32
+ # model: instance of some followable model
33
+
34
+ def followees_of(model)
35
+ model.followees_by_type(self.name)
36
+ end
37
+
38
+ # 4 methods in this function
39
+ #
40
+ # Example:
41
+ # >> Group.with_max_followers
42
+ # => [@ruby]
43
+ # >> Group.with_max_followers_by_type('user')
44
+ # => [@ruby]
45
+
46
+ def method_missing(name, *args)
47
+ if name.to_s =~ /^with_(max|min)_followers$/i
48
+ follow_array = self.all.to_a.sort! { |a, b| a.followers_count <=> b.followers_count }
49
+ if $1 == "max"
50
+ max = follow_array[-1].followers_count
51
+ follow_array.select { |c| c.followers_count == max }
52
+ elsif $1 == "min"
53
+ min = follow_array[0].followers_count
54
+ follow_array.select { |c| c.followers_count == min }
55
+ end
56
+ elsif name.to_s =~ /^with_(max|min)_followers_by_type$/i
57
+ follow_array = self.all.to_a.sort! { |a, b| a.followers_count_by_type(args[0]) <=> b.followers_count_by_type(args[0]) }
58
+ if $1 == "max"
59
+ max = follow_array[-1].followers_count_by_type(args[0])
60
+ follow_array.select { |c| c.followers_count_by_type(args[0]) == max }
61
+ elsif $1 == "min"
62
+ min = follow_array[0].followers_count
63
+ follow_array.select { |c| c.followers_count_by_type(args[0]) == min }
64
+ end
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ # set which mongoid cannot follow self
73
+ #
74
+ # Example:
75
+ # >> @ruby.set_authorization('user')
76
+ # => true
77
+
78
+ def set_authorization(*models)
79
+ models.each do |model|
80
+ self.cannot_followed << model.capitalize
81
+ end
82
+ self.save
83
+ end
84
+
85
+ def unset_authorization(*models)
86
+ models.each do |model|
87
+ self.cannot_followed -= [model.capitalize]
88
+ end
89
+ self.save
90
+ end
91
+
92
+ # see if this model is followee of some model
93
+ #
94
+ # Example:
95
+ # >> @ruby.followee_of?(@jim)
96
+ # => true
97
+
98
+ def followee_of?(model)
99
+ 0 < self.followers.by_model(model).limit(1).count * model.followees.by_model(self).limit(1).count
100
+ end
101
+
102
+ # get all the followers of this model, same with classmethod followers_of
103
+ #
104
+ # Example:
105
+ # >> @ruby.all_followers
106
+ # => [@jim]
107
+
108
+ def all_followers
109
+ rebuild_instances(self.followers)
110
+ end
111
+
112
+ # get all the followers of this model in certain type
113
+ #
114
+ # Example:
115
+ # >> @ruby.followers_by_type("user")
116
+ # => [@jim]
117
+
118
+ def followers_by_type(type)
119
+ rebuild_instances(self.followers.by_type(type))
120
+ end
121
+
122
+ # get the number of followers
123
+ #
124
+ # Example:
125
+ # >> @ruby.followers_count
126
+ # => 1
127
+
128
+ def followers_count
129
+ self.followers.count
130
+ end
131
+
132
+ # get the number of followers in certain type
133
+ #
134
+ # Example:
135
+ # >> @ruby.followers_count_by_type("user")
136
+ # => 1
137
+
138
+ def followers_count_by_type(type)
139
+ self.followers.by_type(type).count
140
+ end
141
+
142
+ # see model's followed history
143
+ #
144
+ # Example:
145
+ # >> @ruby.ever_followed
146
+ # => [@jim]
147
+
148
+ def ever_followed
149
+ follow = []
150
+ self.followed_history.each do |h|
151
+ follow << h.split('_')[0].constantize.find(h.split('_')[1])
152
+ end
153
+ follow
154
+ end
155
+
156
+ # return if there is any common followers
157
+ #
158
+ # Example:
159
+ # >> @ruby.common_followees?(@python)
160
+ # => true
161
+
162
+ def common_followers?(model)
163
+ 0 < (rebuild_instances(self.followers) & rebuild_instances(model.followers)).length
164
+ end
165
+
166
+ # get common followers with some model
167
+ #
168
+ # Example:
169
+ # >> @ruby.common_followers_with(@python)
170
+ # => [@jim]
171
+
172
+ def common_followers_with(model)
173
+ rebuild_instances(self.followers) & rebuild_instances(model.followers)
174
+ end
175
+
176
+ private
177
+ def rebuild_instances(follows)
178
+ follow_list = []
179
+ follows.each do |follow|
180
+ follow_list << follow.f_type.capitalize.constantize.find(follow.f_id)
181
+ end
182
+ follow_list
183
+ end
184
+ end
185
+ end
@@ -0,0 +1,213 @@
1
+ module Mongo
2
+ module Follower
3
+ extend ActiveSupport::Concern
4
+
5
+ included do |base|
6
+ if defined?(Mongoid)
7
+ base.field :cannot_follow, :type => Array, :default => []
8
+ base.field :follow_history, :type => Array, :default => []
9
+ base.has_many :followees, :class_name => "Follow", :as => :following, :dependent => :destroy
10
+ elsif defined?(MongoMapper)
11
+ base.key :cannot_follow, :type => Array, :default => []
12
+ base.key :follow_history, :type => Array, :default => []
13
+ base.many :followees, :class_name => "Follow", :as => :following, :dependent => :destroy
14
+ end
15
+ end
16
+
17
+ module ClassMethods
18
+
19
+ # get certain model's followers of this type
20
+ #
21
+ # Example:
22
+ # >> @jim = User.new
23
+ # >> @ruby = Group.new
24
+ # >> @jim.save
25
+ # >> @ruby.save
26
+ #
27
+ # >> @jim.follow(@ruby)
28
+ # >> User.followers_of(@ruby)
29
+ # => [@jim]
30
+ #
31
+ # Arguments:
32
+ # model: instance of some followable model
33
+
34
+ def followers_of(model)
35
+ model.followers_by_type(self.name)
36
+ end
37
+
38
+ # 4 methods in this function
39
+ #
40
+ # Example:
41
+ # >> User.with_max_followees
42
+ # => [@jim]
43
+ # >> User.with_max_followees_by_type('group')
44
+ # => [@jim]
45
+
46
+ def method_missing(name, *args)
47
+ if name.to_s =~ /^with_(max|min)_followees$/i
48
+ follow_array = self.all.to_a.sort! { |a, b| a.followees_count <=> b.followees_count }
49
+ if $1 == "max"
50
+ max = follow_array[-1].followees_count
51
+ follow_array.select { |c| c.followees_count == max }
52
+ elsif $1 == "min"
53
+ min = follow_array[0].followees_count
54
+ follow_array.select { |c| c.followees_count == min }
55
+ end
56
+ elsif name.to_s =~ /^with_(max|min)_followees_by_type$/i
57
+ follow_array = self.all.to_a.sort! { |a, b| a.followees_count_by_type(args[0]) <=> b.followees_count_by_type(args[0]) }
58
+ if $1 == "max"
59
+ max = follow_array[-1].followees_count_by_type(args[0])
60
+ follow_array.select { |c| c.followees_count_by_type(args[0]) == max }
61
+ elsif $1 == "min"
62
+ min = follow_array[0].followees_count
63
+ follow_array.select { |c| c.followees_count_by_type(args[0]) == min }
64
+ end
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ end
71
+
72
+ # set which mongoid user cannot follow
73
+ #
74
+ # Example:
75
+ # >> @jim.set_authorization('group', 'user')
76
+ # => true
77
+
78
+ def set_authorization(*models)
79
+ models.each do |model|
80
+ self.cannot_follow << model.capitalize
81
+ end
82
+ self.save
83
+ end
84
+
85
+ #unset which mongoid user cannot follow
86
+
87
+ def unset_authorization(*models)
88
+ models.each do |model|
89
+ self.cannot_follow -= [model.capitalize]
90
+ end
91
+ self.save
92
+ end
93
+
94
+ # see if this model is follower of some model
95
+ #
96
+ # Example:
97
+ # >> @jim.follower_of?(@ruby)
98
+ # => true
99
+
100
+ def follower_of?(model)
101
+ 0 < self.followees.by_model(model).limit(1).count * model.followers.by_model(self).limit(1).count
102
+ end
103
+
104
+ # get all the followees of this model, same with classmethod followees_of
105
+ #
106
+ # Example:
107
+ # >> @jim.all_followees
108
+ # => [@ruby]
109
+
110
+ def all_followees
111
+ rebuild_instances(self.followees)
112
+ end
113
+
114
+ # get all the followees of this model in certain type
115
+ #
116
+ # Example:
117
+ # >> @ruby.followees_by_type("group")
118
+ # => [@ruby]
119
+
120
+ def followees_by_type(type)
121
+ rebuild_instances(self.followees.by_type(type))
122
+ end
123
+
124
+ # follow some model
125
+
126
+ def follow(*models)
127
+ models.each do |model|
128
+ unless model == self or self.follower_of?(model) or model.followee_of?(self) or self.cannot_follow.include?(model.class.name) or model.cannot_followed.include?(self.class.name)
129
+ model.followers.create!(:f_type => self.class.name, :f_id => self.id.to_s)
130
+ model.followed_history << self.class.name + '_' + self.id.to_s
131
+ model.save
132
+ self.followees.create!(:f_type => model.class.name, :f_id => model.id.to_s)
133
+ self.follow_history << model.class.name + '_' + model.id.to_s
134
+ self.save
135
+ end
136
+ end
137
+ end
138
+
139
+ # unfollow some model
140
+
141
+ def unfollow(*models)
142
+ models.each do |model|
143
+ unless model == self or !self.follower_of?(model) or !model.followee_of?(self) or self.cannot_follow.include?(model.class.name) or model.cannot_followed.include?(self.class.name)
144
+ model.followers.by_model(self).first.destroy
145
+ self.followees.by_model(model).first.destroy
146
+ end
147
+ end
148
+ end
149
+
150
+ # get the number of followees
151
+ #
152
+ # Example:
153
+ # >> @jim.followers_count
154
+ # => 1
155
+
156
+ def followees_count
157
+ self.followees.count
158
+ end
159
+
160
+ # get the number of followers in certain type
161
+ #
162
+ # Example:
163
+ # >> @ruby.followers_count_by_type("user")
164
+ # => 1
165
+
166
+ def followees_count_by_type(type)
167
+ self.followees.by_type(type).count
168
+ end
169
+
170
+ # see user's follow history
171
+ #
172
+ # Example:
173
+ # >> @jim.ever_follow
174
+ # => [@ruby]
175
+
176
+ def ever_follow
177
+ follow = []
178
+ self.follow_history.each do |h|
179
+ follow << h.split('_')[0].constantize.find(h.split('_')[1])
180
+ end
181
+ follow
182
+ end
183
+
184
+ # return if there is any common followees
185
+ #
186
+ # Example:
187
+ # >> @jim.common_followees?(@tom)
188
+ # => true
189
+
190
+ def common_followees?(model)
191
+ 0 < (rebuild_instances(self.followees) & rebuild_instances(model.followees)).length
192
+ end
193
+
194
+ # get common followees with some model
195
+ #
196
+ # Example:
197
+ # >> @jim.common_followees_with(@tom)
198
+ # => [@ruby]
199
+
200
+ def common_followees_with(model)
201
+ rebuild_instances(self.followees) & rebuild_instances(model.followees)
202
+ end
203
+
204
+ private
205
+ def rebuild_instances(follows)
206
+ follow_list = []
207
+ follows.each do |follow|
208
+ follow_list << follow.f_type.capitalize.constantize.find(follow.f_id)
209
+ end
210
+ follow_list
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,3 @@
1
+ module MongoFollowable
2
+ VERSION = "0.2.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ #require "mongo_followable/followable"
2
+ #require "mongo_followable/follower"
3
+ #require "../app/models/follow"
4
+
5
+ require File.join(File.dirname(__FILE__), "mongo_followable/followable")
6
+ require File.join(File.dirname(__FILE__), "mongo_followable/follower")
7
+ require File.join(File.dirname(__FILE__), "../app/models/follow")
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mongo_followable/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mongo_followable"
7
+ s.version = MongoFollowable::VERSION
8
+ s.authors = ["Jie Fan"]
9
+ s.email = ["ustc.flyingfox@gmail.com"]
10
+ s.homepage = "https://github.com/lastomato/mongo_followable"
11
+ s.summary = %q{ adds following feature to mongoid }
12
+ s.description = %q{ Mongo Followable adds following feature to mongoid }
13
+
14
+ s.rubyforge_project = "mongo_followable"
15
+
16
+ s.add_development_dependency('rspec', '~> 2.6')
17
+ s.add_development_dependency('mongoid', '~> 2.0')
18
+ s.add_development_dependency('mongo_mapper', '~> 0.9')
19
+ s.add_development_dependency('bson_ext', '~> 1.4')
20
+ s.add_development_dependency('database_cleaner', '~>0.6')
21
+
22
+ s.files = `git ls-files`.split("\n")
23
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
24
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
25
+ s.require_paths = ["lib"]
26
+ end
@@ -0,0 +1,126 @@
1
+ require 'spec_helper'
2
+
3
+ describe Mongo::Followable do
4
+
5
+ describe User do
6
+
7
+ let!(:u) { User.new }
8
+
9
+ context "begins" do
10
+
11
+ before do
12
+ u.save
13
+
14
+ @v = User.new
15
+ @v.save
16
+
17
+ @g = Group.new
18
+ @g.save
19
+ end
20
+
21
+ it "following a user" do
22
+ u.follow(@v)
23
+
24
+ u.follower_of?(@v).should be_true
25
+ @v.followee_of?(u).should be_true
26
+
27
+ u.all_followees.should == [@v]
28
+ @v.all_followers.should == [u]
29
+
30
+ u.followees_by_type("user").should == [@v]
31
+ @v.followers_by_type("user").should == [u]
32
+
33
+ u.followees_count.should == 1
34
+ @v.followers_count.should == 1
35
+
36
+ u.followees_count_by_type("user").should == 1
37
+ @v.followers_count_by_type("user").should == 1
38
+
39
+ u.ever_follow.should == [@v]
40
+ @v.ever_followed.should == [u]
41
+
42
+ u.common_followees?(@v).should be_false
43
+ @v.common_followers?(u).should be_false
44
+ u.common_followees_with(@v).should == []
45
+ @v.common_followers_with(u).should == []
46
+
47
+ User.with_max_followees.should == [u]
48
+ User.with_max_followers.should == [@v]
49
+ User.with_max_followees_by_type('user').should == [u]
50
+ User.with_max_followers_by_type('user').should == [@v]
51
+ end
52
+
53
+ it "unfollowing a user" do
54
+ u.unfollow(@v)
55
+
56
+ u.follower_of?(@v).should be_false
57
+ @v.followee_of?(u).should be_false
58
+
59
+ u.all_followees.should == []
60
+ @v.all_followers.should == []
61
+
62
+ u.followees_by_type("user").should == []
63
+ @v.followers_by_type("user").should == []
64
+
65
+ u.followees_count.should == 0
66
+ @v.followers_count.should == 0
67
+
68
+ u.followees_count_by_type("user").should == 0
69
+ @v.followers_count_by_type("user").should == 0
70
+ end
71
+
72
+ it "following a group" do
73
+ u.follow(@g)
74
+
75
+ u.follower_of?(@g).should be_true
76
+ @g.followee_of?(u).should be_true
77
+
78
+ u.all_followees.should == [@g]
79
+ @g.all_followers.should == [u]
80
+
81
+ u.followees_by_type("group").should == [@g]
82
+ @g.followers_by_type("user").should == [u]
83
+
84
+ u.followees_count.should == 1
85
+ @g.followers_count.should == 1
86
+
87
+ u.followees_count_by_type("group").should == 1
88
+ @g.followers_count_by_type("user").should == 1
89
+
90
+ u.follow(@v)
91
+
92
+ u.ever_follow.should == [@g, @v]
93
+ @g.ever_followed.should == [u]
94
+
95
+ u.common_followees?(@v).should be_false
96
+ @v.common_followers?(@g).should be_true
97
+ u.common_followees_with(@v).should == []
98
+ @v.common_followers_with(@g).should == [u]
99
+
100
+ User.with_max_followees.should == [u]
101
+ Group.with_max_followers.should == [@g]
102
+ User.with_max_followees_by_type('group').should == [u]
103
+ Group.with_max_followers_by_type('user').should == [@g]
104
+ end
105
+
106
+ it "unfollowing a group" do
107
+ u.unfollow(@g)
108
+
109
+ u.follower_of?(@g).should be_false
110
+ @g.followee_of?(u).should be_false
111
+
112
+ u.all_followees.should == []
113
+ @g.all_followers.should == []
114
+
115
+ u.followees_by_type("group").should == []
116
+ @g.followers_by_type("group").should == []
117
+
118
+ u.followees_count.should == 0
119
+ @g.followers_count.should == 0
120
+
121
+ u.followees_count_by_type("group").should == 0
122
+ @g.followers_count_by_type("group").should == 0
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,4 @@
1
+ class Group
2
+ include MongoMapper::Document
3
+ include Mongo::Followable
4
+ end
@@ -0,0 +1,5 @@
1
+ class User
2
+ include MongoMapper::Document
3
+ include Mongo::Followable
4
+ include Mongo::Follower
5
+ end
@@ -0,0 +1,4 @@
1
+ class Group
2
+ include Mongoid::Document
3
+ include Mongo::Followable
4
+ end
@@ -0,0 +1,5 @@
1
+ class User
2
+ include Mongoid::Document
3
+ include Mongo::Followable
4
+ include Mongo::Follower
5
+ end
@@ -0,0 +1,31 @@
1
+ require "rubygems"
2
+ require "bundler/setup"
3
+
4
+ require "database_cleaner"
5
+ require "rspec"
6
+
7
+ if rand > 0.5
8
+ puts 'Mongoid'
9
+ require 'mongoid'
10
+ require File.expand_path("../../lib/mongo_followable", __FILE__)
11
+ require File.expand_path("../mongoid/user", __FILE__)
12
+ require File.expand_path("../mongoid/group", __FILE__)
13
+ Mongoid.configure do |config|
14
+ name = 'voteable_mongo_test'
15
+ host = 'localhost'
16
+ config.master = Mongo::Connection.new.db(name)
17
+ config.autocreate_indexes = true
18
+ end
19
+ else
20
+ puts 'MongoMapper'
21
+ require 'mongo_mapper'
22
+ require File.expand_path("../../lib/mongo_followable", __FILE__)
23
+ require File.expand_path("../mongo_mapper/user", __FILE__)
24
+ require File.expand_path("../mongo_mapper/group", __FILE__)
25
+ MongoMapper.database = 'voteable_mongo_test'
26
+ end
27
+
28
+ RSpec.configure do |c|
29
+ c.before(:all) { DatabaseCleaner.strategy = :truncation }
30
+ c.before(:each) { DatabaseCleaner.clean }
31
+ end
metadata ADDED
@@ -0,0 +1,150 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mongo_followable
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 0
9
+ version: 0.2.0
10
+ platform: ruby
11
+ authors:
12
+ - Jie Fan
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2011-11-06 01:00:00 -04:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 2
30
+ - 6
31
+ version: "2.6"
32
+ type: :development
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: mongoid
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ~>
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 2
44
+ - 0
45
+ version: "2.0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ - !ruby/object:Gem::Dependency
49
+ name: mongo_mapper
50
+ prerelease: false
51
+ requirement: &id003 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ segments:
57
+ - 0
58
+ - 9
59
+ version: "0.9"
60
+ type: :development
61
+ version_requirements: *id003
62
+ - !ruby/object:Gem::Dependency
63
+ name: bson_ext
64
+ prerelease: false
65
+ requirement: &id004 !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ~>
69
+ - !ruby/object:Gem::Version
70
+ segments:
71
+ - 1
72
+ - 4
73
+ version: "1.4"
74
+ type: :development
75
+ version_requirements: *id004
76
+ - !ruby/object:Gem::Dependency
77
+ name: database_cleaner
78
+ prerelease: false
79
+ requirement: &id005 !ruby/object:Gem::Requirement
80
+ none: false
81
+ requirements:
82
+ - - ~>
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ - 6
87
+ version: "0.6"
88
+ type: :development
89
+ version_requirements: *id005
90
+ description: " Mongo Followable adds following feature to mongoid "
91
+ email:
92
+ - ustc.flyingfox@gmail.com
93
+ executables: []
94
+
95
+ extensions: []
96
+
97
+ extra_rdoc_files: []
98
+
99
+ files:
100
+ - .gitignore
101
+ - Gemfile
102
+ - LICENSE.txt
103
+ - README.rdoc
104
+ - Rakefile
105
+ - app/models/follow.rb
106
+ - lib/mongo_followable.rb
107
+ - lib/mongo_followable/followable.rb
108
+ - lib/mongo_followable/follower.rb
109
+ - lib/mongo_followable/version.rb
110
+ - mongo_followable.gemspec
111
+ - spec/mongo/followable_spec.rb
112
+ - spec/mongo_mapper/group.rb
113
+ - spec/mongo_mapper/user.rb
114
+ - spec/mongoid/group.rb
115
+ - spec/mongoid/user.rb
116
+ - spec/spec_helper.rb
117
+ has_rdoc: true
118
+ homepage: https://github.com/lastomato/mongo_followable
119
+ licenses: []
120
+
121
+ post_install_message:
122
+ rdoc_options: []
123
+
124
+ require_paths:
125
+ - lib
126
+ required_ruby_version: !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ segments:
132
+ - 0
133
+ version: "0"
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ none: false
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ segments:
140
+ - 0
141
+ version: "0"
142
+ requirements: []
143
+
144
+ rubyforge_project: mongo_followable
145
+ rubygems_version: 1.3.7
146
+ signing_key:
147
+ specification_version: 3
148
+ summary: adds following feature to mongoid
149
+ test_files: []
150
+