mongo_followable 0.3.0 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,5 @@
1
- module MongoFollowable
2
- VERSION = "0.3.0"
1
+ module Mongo
2
+ module Followable
3
+ VERSION = "0.3.2"
4
+ end
3
5
  end
@@ -4,7 +4,7 @@ require "mongo_followable/version"
4
4
 
5
5
  Gem::Specification.new do |s|
6
6
  s.name = "mongo_followable"
7
- s.version = MongoFollowable::VERSION
7
+ s.version = Mongo::Followable::VERSION
8
8
  s.authors = ["Jie Fan"]
9
9
  s.email = ["ustc.flyingfox@gmail.com"]
10
10
  s.homepage = "https://github.com/lastomato/mongo_followable"
@@ -13,11 +13,11 @@ Gem::Specification.new do |s|
13
13
 
14
14
  s.rubyforge_project = "mongo_followable"
15
15
 
16
- s.add_development_dependency('rspec', '~> 2.7.0')
17
- s.add_development_dependency('mongoid', '~> 2.4.0')
18
- s.add_development_dependency('mongo_mapper', '~> 0.10.0')
19
- s.add_development_dependency('bson_ext', '~> 1.5.0')
20
- s.add_development_dependency('database_cleaner', '~>0.7.0')
16
+ s.add_development_dependency('rspec', '> 2.7.0')
17
+ s.add_development_dependency('mongoid', '> 2.4.0')
18
+ s.add_development_dependency('mongo_mapper', '> 0.10.0')
19
+ s.add_development_dependency('bson_ext', '> 1.5.0')
20
+ s.add_development_dependency('database_cleaner', '>0.7.0')
21
21
 
22
22
  s.files = `git ls-files`.split("\n")
23
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
@@ -46,6 +46,10 @@ describe Mongo::Followable do
46
46
  u.ever_follow.should =~ [@v, @g]
47
47
  @v.ever_followed.should == [u]
48
48
 
49
+ u.ever_follow?(@v).should be_true
50
+ u.ever_follow?(@g).should be_true
51
+ @v.ever_followed?(u).should be_true
52
+
49
53
  u.common_followees?(@v).should be_false
50
54
  @v.common_followers?(u).should be_false
51
55
  u.common_followees_with(@v).should == []
@@ -99,6 +103,12 @@ describe Mongo::Followable do
99
103
  u.ever_follow.should =~ [@g, @v]
100
104
  @g.ever_followed.should == [u]
101
105
 
106
+ u.clear_follow_history!
107
+ u.ever_follow.should == []
108
+
109
+ @g.clear_history!
110
+ @g.ever_followed.should == []
111
+
102
112
  u.common_followees?(@v).should be_false
103
113
  @v.common_followers?(@g).should be_true
104
114
  u.common_followees_with(@v).should == []
@@ -0,0 +1,29 @@
1
+ require "benchmark"
2
+ require "rubygems"
3
+ require "bundler/setup"
4
+ require "mongoid"
5
+ require "../../lib/mongo_followable"
6
+ require "../../spec/mongoid/group"
7
+ require "../../spec/mongoid/user"
8
+
9
+ Mongoid.configure do |config|
10
+ name = 'mongo_followable_test'
11
+ host = 'localhost'
12
+ config.master = Mongo::Connection.new.db(name)
13
+ config.autocreate_indexes = true
14
+ end
15
+
16
+ users = []
17
+ 1000.times { users << User.create! }
18
+ group = Group.create!
19
+
20
+ users.each { |u| u.follow(group) }
21
+
22
+ Benchmark.bmbm do |x|
23
+ x.report("before") { group.followers }
24
+ end
25
+
26
+ RSpec.configure do |c|
27
+ c.before(:all) { DatabaseCleaner.strategy = :truncation }
28
+ c.before(:each) { DatabaseCleaner.clean }
29
+ end
@@ -1,5 +1,6 @@
1
1
  class ChildUser
2
2
  include MongoMapper::Document
3
- include Mongo::Followable
4
- include Mongo::Follower
3
+ include Mongo::Followable::Followed
4
+ include Mongo::Followable::Follower
5
+ include Mongo::Followable::History
5
6
  end
@@ -1,4 +1,5 @@
1
1
  class Group
2
2
  include MongoMapper::Document
3
- include Mongo::Followable
3
+ include Mongo::Followable::Followed
4
+ include Mongo::Followable::History
4
5
  end
@@ -1,5 +1,6 @@
1
1
  class User
2
2
  include MongoMapper::Document
3
- include Mongo::Followable
4
- include Mongo::Follower
3
+ include Mongo::Followable::Followed
4
+ include Mongo::Followable::Follower
5
+ include Mongo::Followable::History
5
6
  end
@@ -1,5 +1,6 @@
1
1
  class ChildUser
2
2
  include Mongoid::Document
3
- include Mongo::Followable
4
- include Mongo::Follower
3
+ include Mongo::Followable::Followed
4
+ include Mongo::Followable::Follower
5
+ include Mongo::Followable::History
5
6
  end
@@ -1,4 +1,5 @@
1
1
  class Group
2
2
  include Mongoid::Document
3
- include Mongo::Followable
3
+ include Mongo::Followable::Followed
4
+ include Mongo::Followable::History
4
5
  end
data/spec/mongoid/user.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  class User
2
2
  include Mongoid::Document
3
- include Mongo::Followable
4
- include Mongo::Follower
3
+ include Mongo::Followable::Followed
4
+ include Mongo::Followable::Follower
5
+ include Mongo::Followable::History
5
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_followable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,14 +9,14 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-05-31 00:00:00.000000000 Z
12
+ date: 2012-08-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
- - - ~>
19
+ - - ! '>'
20
20
  - !ruby/object:Gem::Version
21
21
  version: 2.7.0
22
22
  type: :development
@@ -24,7 +24,7 @@ dependencies:
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  none: false
26
26
  requirements:
27
- - - ~>
27
+ - - ! '>'
28
28
  - !ruby/object:Gem::Version
29
29
  version: 2.7.0
30
30
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
- - - ~>
35
+ - - ! '>'
36
36
  - !ruby/object:Gem::Version
37
37
  version: 2.4.0
38
38
  type: :development
@@ -40,7 +40,7 @@ dependencies:
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
- - - ~>
43
+ - - ! '>'
44
44
  - !ruby/object:Gem::Version
45
45
  version: 2.4.0
46
46
  - !ruby/object:Gem::Dependency
@@ -48,7 +48,7 @@ dependencies:
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
51
- - - ~>
51
+ - - ! '>'
52
52
  - !ruby/object:Gem::Version
53
53
  version: 0.10.0
54
54
  type: :development
@@ -56,7 +56,7 @@ dependencies:
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  none: false
58
58
  requirements:
59
- - - ~>
59
+ - - ! '>'
60
60
  - !ruby/object:Gem::Version
61
61
  version: 0.10.0
62
62
  - !ruby/object:Gem::Dependency
@@ -64,7 +64,7 @@ dependencies:
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
67
- - - ~>
67
+ - - ! '>'
68
68
  - !ruby/object:Gem::Version
69
69
  version: 1.5.0
70
70
  type: :development
@@ -72,7 +72,7 @@ dependencies:
72
72
  version_requirements: !ruby/object:Gem::Requirement
73
73
  none: false
74
74
  requirements:
75
- - - ~>
75
+ - - ! '>'
76
76
  - !ruby/object:Gem::Version
77
77
  version: 1.5.0
78
78
  - !ruby/object:Gem::Dependency
@@ -80,7 +80,7 @@ dependencies:
80
80
  requirement: !ruby/object:Gem::Requirement
81
81
  none: false
82
82
  requirements:
83
- - - ~>
83
+ - - ! '>'
84
84
  - !ruby/object:Gem::Version
85
85
  version: 0.7.0
86
86
  type: :development
@@ -88,7 +88,7 @@ dependencies:
88
88
  version_requirements: !ruby/object:Gem::Requirement
89
89
  none: false
90
90
  requirements:
91
- - - ~>
91
+ - - ! '>'
92
92
  - !ruby/object:Gem::Version
93
93
  version: 0.7.0
94
94
  description: ! ' Mongo Followable adds following feature to mongoid/mongo_mapper '
@@ -99,11 +99,6 @@ extensions: []
99
99
  extra_rdoc_files: []
100
100
  files:
101
101
  - .gitignore
102
- - .idea/encodings.xml
103
- - .idea/misc.xml
104
- - .idea/modules.xml
105
- - .idea/mongo_followable.iml
106
- - .idea/vcs.xml
107
102
  - .rakeTasks
108
103
  - Gemfile
109
104
  - LICENSE.txt
@@ -112,12 +107,15 @@ files:
112
107
  - app/models/follow.rb
113
108
  - lib/mongo_followable.rb
114
109
  - lib/mongo_followable/core_ext/string.rb
115
- - lib/mongo_followable/followable.rb
110
+ - lib/mongo_followable/features/authorization.rb
111
+ - lib/mongo_followable/features/confirmation.rb
112
+ - lib/mongo_followable/features/history.rb
113
+ - lib/mongo_followable/followed.rb
116
114
  - lib/mongo_followable/follower.rb
117
- - lib/mongo_followable/railtie.rb
118
115
  - lib/mongo_followable/version.rb
119
116
  - mongo_followable.gemspec
120
117
  - spec/mongo/followable_spec.rb
118
+ - spec/mongo/performance_spec.rb
121
119
  - spec/mongo_mapper/childuser.rb
122
120
  - spec/mongo_mapper/group.rb
123
121
  - spec/mongo_mapper/user.rb
@@ -145,7 +143,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
143
  version: '0'
146
144
  requirements: []
147
145
  rubyforge_project: mongo_followable
148
- rubygems_version: 1.8.22
146
+ rubygems_version: 1.8.24
149
147
  signing_key:
150
148
  specification_version: 3
151
149
  summary: adds following feature to mongoid/mongo_mapper
data/.idea/encodings.xml DELETED
@@ -1,5 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
4
- </project>
5
-
data/.idea/misc.xml DELETED
@@ -1,5 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectRootManager" version="2" project-jdk-name="RVM: ruby-1.9.3-p125" project-jdk-type="RUBY_SDK" />
4
- </project>
5
-
data/.idea/modules.xml DELETED
@@ -1,9 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="ProjectModuleManager">
4
- <modules>
5
- <module fileurl="file://$PROJECT_DIR$/.idea/mongo_followable.iml" filepath="$PROJECT_DIR$/.idea/mongo_followable.iml" />
6
- </modules>
7
- </component>
8
- </project>
9
-
@@ -1,17 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <module type="RUBY_MODULE" version="4">
3
- <component name="NewModuleRootManager">
4
- <content url="file://$MODULE_DIR$" />
5
- <orderEntry type="inheritedJdk" />
6
- <orderEntry type="sourceFolder" forTests="false" />
7
- <orderEntry type="library" scope="PROVIDED" name="builder (v3.0.0, RVM: ruby-1.9.3-p125) [gem]" level="application" />
8
- <orderEntry type="library" scope="PROVIDED" name="bundler (v1.1.3, RVM: ruby-1.9.3-p125) [gem]" level="application" />
9
- <orderEntry type="library" scope="PROVIDED" name="diff-lcs (v1.1.3, RVM: ruby-1.9.3-p125) [gem]" level="application" />
10
- <orderEntry type="library" scope="PROVIDED" name="i18n (v0.6.0, RVM: ruby-1.9.3-p125) [gem]" level="application" />
11
- <orderEntry type="library" scope="PROVIDED" name="mongo (v1.5.2, RVM: ruby-1.9.3-p125) [gem]" level="application" />
12
- <orderEntry type="library" scope="PROVIDED" name="mongoid (v2.4.7, RVM: ruby-1.9.3-p125) [gem]" level="application" />
13
- <orderEntry type="library" scope="PROVIDED" name="multi_json (v1.0.4, RVM: ruby-1.9.3-p125) [gem]" level="application" />
14
- <orderEntry type="library" scope="PROVIDED" name="rspec (v2.7.0, RVM: ruby-1.9.3-p125) [gem]" level="application" />
15
- </component>
16
- </module>
17
-
data/.idea/vcs.xml DELETED
@@ -1,7 +0,0 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <project version="4">
3
- <component name="VcsDirectoryMappings">
4
- <mapping directory="$PROJECT_DIR$" vcs="Git" />
5
- </component>
6
- </project>
7
-
@@ -1,247 +0,0 @@
1
- module Mongo
2
- module Followable
3
- extend ActiveSupport::Concern
4
-
5
- included do |base|
6
- if defined?(Mongoid)
7
- if CONFIG[:authorization]
8
- base.field :cannot_followed, :type => Array, :default => []
9
- end
10
-
11
- if CONFIG[:history]
12
- base.field :followed_history, :type => Array, :default => []
13
- end
14
-
15
- base.has_many :followers, :class_name => "Follow", :as => :followable, :dependent => :destroy
16
- elsif defined?(MongoMapper)
17
- if CONFIG[:authorization]
18
- base.key :cannot_followed, :type => Array, :default => []
19
- end
20
-
21
- if CONFIG[:history]
22
- base.key :followed_history, :type => Array, :default => []
23
- end
24
-
25
- base.many :followers, :class_name => "Follow", :as => :followable, :dependent => :destroy
26
- end
27
- end
28
-
29
- module ClassMethods
30
-
31
- # get certain model's followees of this type
32
- #
33
- # Example:
34
- # >> @jim = User.new
35
- # >> @ruby = Group.new
36
- # >> @jim.save
37
- # >> @ruby.save
38
- #
39
- # >> @jim.follow(@ruby)
40
- # >> User.followees_of(@jim)
41
- # => [@ruby]
42
- #
43
- # Arguments:
44
- # model: instance of some followable model
45
-
46
- def followees_of(model)
47
- model.followees_by_type(self.name)
48
- end
49
-
50
- # 4 methods in this function
51
- #
52
- # Example:
53
- # >> Group.with_max_followers
54
- # => [@ruby]
55
- # >> Group.with_max_followers_by_type('user')
56
- # => [@ruby]
57
-
58
- ["max", "min"].each do |s|
59
- define_method(:"with_#{s}_followers") do
60
- follow_array = self.all.to_a.sort! { |a, b| a.followers_count <=> b.followers_count }
61
- num = follow_array[-1].followers_count
62
- follow_array.select { |c| c.followers_count == num }
63
- end
64
-
65
- define_method(:"with_#{s}_followers_by_type") do |*args|
66
- follow_array = self.all.to_a.sort! { |a, b| a.followers_count_by_type(args[0]) <=> b.followers_count_by_type(args[0]) }
67
- num = follow_array[-1].followers_count_by_type(args[0])
68
- follow_array.select { |c| c.followers_count_by_type(args[0]) == num }
69
- end
70
- end
71
-
72
- #def method_missing(name, *args)
73
- # if name.to_s =~ /^with_(max|min)_followers$/i
74
- # follow_array = self.all.to_a.sort! { |a, b| a.followers_count <=> b.followers_count }
75
- # if $1 == "max"
76
- # max = follow_array[-1].followers_count
77
- # follow_array.select { |c| c.followers_count == max }
78
- # elsif $1 == "min"
79
- # min = follow_array[0].followers_count
80
- # follow_array.select { |c| c.followers_count == min }
81
- # end
82
- # elsif name.to_s =~ /^with_(max|min)_followers_by_type$/i
83
- # follow_array = self.all.to_a.sort! { |a, b| a.followers_count_by_type(args[0]) <=> b.followers_count_by_type(args[0]) }
84
- # if $1 == "max"
85
- # max = follow_array[-1].followers_count_by_type(args[0])
86
- # follow_array.select { |c| c.followers_count_by_type(args[0]) == max }
87
- # elsif $1 == "min"
88
- # min = follow_array[0].followers_count
89
- # follow_array.select { |c| c.followers_count_by_type(args[0]) == min }
90
- # end
91
- # else
92
- # super
93
- # end
94
- #end
95
-
96
- end
97
-
98
- # set which mongoid cannot follow self
99
- #
100
- # Example:
101
- # >> @ruby.set_authorization('user')
102
- # => true
103
-
104
- if CONFIG[:authorization]
105
- define_method(:set_authorization) do |*models|
106
- models.each do |model|
107
-
108
- self.cannot_followed << model.safe_capitalize
109
- end
110
- self.save
111
- end
112
-
113
- define_method(:unset_authorization) do |*models|
114
- models.each do |model|
115
- self.cannot_followed -= [model.safe_capitalize]
116
- end
117
- self.save
118
- end
119
- end
120
-
121
- # see if this model is followee of some model
122
- #
123
- # Example:
124
- # >> @ruby.followee_of?(@jim)
125
- # => true
126
-
127
- def followee_of?(model)
128
- 0 < self.followers.by_model(model).limit(1).count * model.followees.by_model(self).limit(1).count
129
- end
130
-
131
- # return true if self is followed by some models
132
- #
133
- # Example:
134
- # >> @ruby.followed?
135
- # => true
136
-
137
- def followed?
138
- 0 < self.followers.length
139
- end
140
-
141
- # get all the followers of this model, same with classmethod followers_of
142
- #
143
- # Example:
144
- # >> @ruby.all_followers
145
- # => [@jim]
146
-
147
- def all_followers
148
- rebuild_instances(self.followers)
149
- end
150
-
151
- def unfollowed(*models, &block)
152
- if block_given?
153
- models.delete_if { |model| !yield(model) }
154
- end
155
-
156
- models.each do |model|
157
- term = CONFIG[:authorization] ? (self.cannot_followed.include?(model.class.name) or model.cannot_follow.include?(self.class.name)) : false
158
-
159
- unless model == self or !self.followee_of?(model) or !model.follower_of?(self) or term
160
- model.followees.by_model(self).first.destroy
161
- self.followers.by_model(model).first.destroy
162
- end
163
- end
164
- end
165
-
166
- # unfollow all
167
-
168
- def unfollowed_all
169
- unfollowed(*self.all_followers)
170
- end
171
-
172
- # get all the followers of this model in certain type
173
- #
174
- # Example:
175
- # >> @ruby.followers_by_type("user")
176
- # => [@jim]
177
-
178
- def followers_by_type(type)
179
- rebuild_instances(self.followers.by_type(type))
180
- end
181
-
182
- # get the number of followers
183
- #
184
- # Example:
185
- # >> @ruby.followers_count
186
- # => 1
187
-
188
- def followers_count
189
- self.followers.count
190
- end
191
-
192
- # get the number of followers in certain type
193
- #
194
- # Example:
195
- # >> @ruby.followers_count_by_type("user")
196
- # => 1
197
-
198
- def followers_count_by_type(type)
199
- self.followers.by_type(type).count
200
- end
201
-
202
- # see model's followed history
203
- #
204
- # Example:
205
- # >> @ruby.ever_followed
206
- # => [@jim]
207
-
208
- if CONFIG[:history]
209
- define_method(:ever_followed) do
210
- follow = []
211
- self.followed_history.each do |h|
212
- follow << h.split('_')[0].constantize.find(h.split('_')[1])
213
- end
214
- follow
215
- end
216
- end
217
-
218
- # return if there is any common followers
219
- #
220
- # Example:
221
- # >> @ruby.common_followees?(@python)
222
- # => true
223
-
224
- def common_followers?(model)
225
- 0 < (rebuild_instances(self.followers) & rebuild_instances(model.followers)).length
226
- end
227
-
228
- # get common followers with some model
229
- #
230
- # Example:
231
- # >> @ruby.common_followers_with(@python)
232
- # => [@jim]
233
-
234
- def common_followers_with(model)
235
- rebuild_instances(self.followers) & rebuild_instances(model.followers)
236
- end
237
-
238
- private
239
- def rebuild_instances(follows)
240
- follow_list = []
241
- follows.each do |follow|
242
- follow_list << follow.f_type.constantize.find(follow.f_id)
243
- end
244
- follow_list
245
- end
246
- end
247
- end