mongoid_follow 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -48,6 +48,40 @@ You can also be a follower of other models
48
48
  @gang.follower?(@bonnie)
49
49
  @bonnie.follows?(@gang)
50
50
 
51
+ === Getting followers/followees
52
+
53
+ Get all followers/followees by
54
+
55
+ @gang.all_followers
56
+ @bonnie.all_followees
57
+
58
+ You can also get followers/followees by a certain model
59
+
60
+ @gang.all_followers_by_model(User)
61
+ @bonnie.all_followees_by_model(Gang)
62
+
63
+ === Counting followers/followees
64
+
65
+ Get the count of followers/followees using
66
+
67
+ @gang.followers_count
68
+ @bonnie.followees_count
69
+
70
+ Or by a certain model by
71
+
72
+ @gang.followers_count_by_model(User)
73
+ @bonnie.followees_count_by_model(User)
74
+
75
+ === Dynamic methods
76
+
77
+ You can use dynamic methods to shorten code for getting followers/followees or their count of a certain model by
78
+
79
+ @gang.all_user_followers
80
+ @bonnie.all_gang_followees
81
+
82
+ @gang.user_followers_count
83
+ @bonnie.user_followees_count
84
+
51
85
  == Callbacks
52
86
 
53
87
  You can attach callbacks to the follower/followee models before or after the follow.
@@ -73,7 +107,7 @@ You can attach callbacks to the follower/followee models before or after the fol
73
107
  before_unfollowed_by
74
108
  after_unfollowed_by
75
109
 
76
- * Note: careful with using callbacks, we have no transaction so if breaks on your callbacks, what gets saved is saved.
110
+ Note: careful with using callbacks, we have no transaction so if it breaks on your callbacks, what gets saved is saved.
77
111
 
78
112
  * Any bug or issue, please send me an email to aeguintu@gmail.com
79
113
 
@@ -88,15 +122,13 @@ You can attach callbacks to the follower/followee models before or after the fol
88
122
 
89
123
  == TODO
90
124
 
91
- * finish up todo's (list of followers and followees) ==FINISHED
92
- * count of followers/followees ==FINISHED
93
- * common followers (or maybe followees) ==FINISHED
125
+ * limit result of followers/followees
94
126
 
95
127
  == Thanks
96
128
 
97
- Super thanks:
98
- to mongoid_followable.
99
- to Tristan Peralta.
129
+ Awesome thanks to:
130
+ to mongoid_followable
131
+ to Tristan Peralta
100
132
 
101
133
  == Copyright
102
134
 
@@ -1,3 +1,4 @@
1
1
  require File.join(File.dirname(__FILE__), "mongoid_follow/follower")
2
2
  require File.join(File.dirname(__FILE__), "mongoid_follow/followee")
3
+ require File.join(File.dirname(__FILE__), "mongoid_follow/helper")
3
4
  require File.join(File.dirname(__FILE__), "../app/models/follow")
@@ -10,34 +10,53 @@ module Mongoid
10
10
  # know if self is followed by model
11
11
  #
12
12
  # Example:
13
- # >> @clyde.follower?(@bonnie)
13
+ # => @clyde.follower?(@bonnie)
14
14
  # => true
15
15
  def follower?(model)
16
16
  0 < self.followers.find(:all, conditions: {ff_id: model.id}).limit(1).count
17
17
  end
18
18
 
19
- # get followees count
19
+ # get followers count
20
+ # Note: this is a cache counter
20
21
  #
21
22
  # Example:
22
- # >> @bonnie.followees_count
23
+ # => @bonnie.followers_count
23
24
  # => 1
24
25
  def followers_count
25
26
  self.fferc
26
27
  end
27
28
 
29
+ # get followers count by model
30
+ #
31
+ # Example:
32
+ # => @bonnie.followers_count_by_model(User)
33
+ # => 1
34
+ def followers_count_by_model(model)
35
+ self.followers.where(:ff_type => model.to_s).count
36
+ end
37
+
28
38
  # view all selfs followers
29
39
  #
30
40
  # Example:
31
- # >> @clyde.all_followers
41
+ # => @clyde.all_followers
32
42
  # => [@bonnie, @alec]
33
43
  def all_followers
34
44
  get_followers_of(self)
35
45
  end
36
46
 
47
+ # view all selfs followers by model
48
+ #
49
+ # Example:
50
+ # => @clyde.all_followers_by_model
51
+ # => [@bonnie]
52
+ def all_followers_by_model(model)
53
+ get_followers_of(self, model)
54
+ end
55
+
37
56
  # view all common followers of self against model
38
57
  #
39
58
  # Example:
40
- # >> @clyde.common_followers_with(@gang)
59
+ # => @clyde.common_followers_with(@gang)
41
60
  # => [@bonnie, @alec]
42
61
  def common_followers_with(model)
43
62
  model_followers = get_followers_of(model)
@@ -47,10 +66,22 @@ module Mongoid
47
66
  end
48
67
 
49
68
  private
50
- def get_followers_of(me)
51
- me.followers.collect do |f|
69
+ def get_followers_of(me, model = nil)
70
+ followers = !model ? me.followers : me.followers.where(:ff_type => model.to_s)
71
+
72
+ followers.collect do |f|
52
73
  f.ff_type.constantize.find(f.ff_id)
53
74
  end
54
75
  end
76
+
77
+ def method_missing(missing_method, *args, &block)
78
+ if missing_method.to_s =~ /^(.+)_followers_count$/
79
+ followers_count_by_model($1.camelize)
80
+ elsif missing_method.to_s =~ /^all_(.+)_followers$/
81
+ all_followers_by_model($1.camelize)
82
+ else
83
+ super
84
+ end
85
+ end
55
86
  end
56
87
  end
@@ -10,7 +10,7 @@ module Mongoid
10
10
  # follow a model
11
11
  #
12
12
  # Example:
13
- # >> @bonnie.follow(@clyde)
13
+ # => @bonnie.follow(@clyde)
14
14
  def follow(model)
15
15
  if self.id != model.id && !self.follows?(model)
16
16
 
@@ -32,7 +32,7 @@ module Mongoid
32
32
  # unfollow a model
33
33
  #
34
34
  # Example:
35
- # >> @bonnie.unfollow(@clyde)
35
+ # => @bonnie.unfollow(@clyde)
36
36
  def unfollow(model)
37
37
  if self.id != model.id && self.follows?(model)
38
38
 
@@ -54,34 +54,53 @@ module Mongoid
54
54
  # know if self is already following model
55
55
  #
56
56
  # Example:
57
- # >> @bonnie.follows?(@clyde)
57
+ # => @bonnie.follows?(@clyde)
58
58
  # => true
59
59
  def follows?(model)
60
60
  0 < self.followees.find(:all, conditions: {ff_id: model.id}).limit(1).count
61
61
  end
62
62
 
63
63
  # get followees count
64
+ # Note: this is a cache counter
64
65
  #
65
66
  # Example:
66
- # >> @bonnie.followees_count
67
+ # => @bonnie.followees_count
67
68
  # => 1
68
69
  def followees_count
69
70
  self.ffeec
70
71
  end
71
72
 
73
+ # get followees count by model
74
+ #
75
+ # Example:
76
+ # => @bonnie.followees_count_by_model(User)
77
+ # => 1
78
+ def followees_count_by_model(model)
79
+ self.followees.where(:ff_type => model.to_s).count
80
+ end
81
+
72
82
  # view all selfs followees
73
83
  #
74
84
  # Example:
75
- # >> @alec.all_followees
85
+ # => @alec.all_followees
76
86
  # => [@bonnie]
77
87
  def all_followees
78
88
  get_followees_of(self)
79
89
  end
80
90
 
91
+ # view all selfs followees by model
92
+ #
93
+ # Example:
94
+ # => @clyde.all_followees_by_model
95
+ # => [@bonnie]
96
+ def all_followees_by_model(model)
97
+ get_followees_of(self, model)
98
+ end
99
+
81
100
  # view all common followees of self against model
82
101
  #
83
102
  # Example:
84
- # >> @clyde.common_followees_with(@gang)
103
+ # => @clyde.common_followees_with(@gang)
85
104
  # => [@bonnie, @alec]
86
105
  def common_followees_with(model)
87
106
  model_followees = get_followees_of(model)
@@ -91,10 +110,22 @@ module Mongoid
91
110
  end
92
111
 
93
112
  private
94
- def get_followees_of(me)
95
- me.followees.collect do |f|
113
+ def get_followees_of(me, model = nil)
114
+ followees = !model ? me.followees : me.followees.where(:ff_type => model.to_s)
115
+
116
+ followees.collect do |f|
96
117
  f.ff_type.constantize.find(f.ff_id)
97
118
  end
98
119
  end
120
+
121
+ def method_missing(missing_method, *args, &block)
122
+ if missing_method.to_s =~ /^(.+)_followees_count$/
123
+ followees_count_by_model($1.camelize)
124
+ elsif missing_method.to_s =~ /^all_(.+)_followees$/
125
+ all_followees_by_model($1.camelize)
126
+ else
127
+ super
128
+ end
129
+ end
99
130
  end
100
131
  end
@@ -0,0 +1,5 @@
1
+ class String
2
+ def camelize
3
+ self.to_s.gsub(/\/(.?)/) { "::" + $1.upcase }.gsub(/(^|_)(.)/) { $2.upcase }
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module MongoidFollow
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -0,0 +1,6 @@
1
+ class OtherUser
2
+ include Mongoid::Document
3
+ include Mongoid::Follower
4
+
5
+ field :name
6
+ end
data/spec/spec_helper.rb CHANGED
@@ -11,6 +11,7 @@ end
11
11
 
12
12
  require File.expand_path("../../lib/mongoid_follow", __FILE__)
13
13
  require File.expand_path("../models/user", __FILE__)
14
+ require File.expand_path("../models/other_user", __FILE__)
14
15
  require File.expand_path("../models/group", __FILE__)
15
16
 
16
17
  RSpec.configure do |c|
@@ -8,6 +8,7 @@ describe Mongoid::Follower do
8
8
  @bonnie = User.create(:name => 'Bonnie')
9
9
  @clyde = User.create(:name => 'Clyde')
10
10
  @alec = User.create(:name => 'Alec')
11
+ @just_another_user = OtherUser.create(:name => 'Another User')
11
12
 
12
13
  @gang = Group.create(:name => 'Gang')
13
14
  end
@@ -65,75 +66,145 @@ describe Mongoid::Follower do
65
66
  @gang.follower?(@bonnie).should be_true
66
67
  end
67
68
 
68
- it "should increment / decrement counters" do
69
- @clyde.followers_count.should == 0
69
+ describe "counting stuff" do
70
+ it "should increment / decrement cache counters" do
71
+ @clyde.followers_count.should == 0
70
72
 
71
- @bonnie.follow(@clyde)
73
+ @bonnie.follow(@clyde)
74
+ @bonnie.followees_count.should == 1
75
+ @clyde.followers_count.should == 1
72
76
 
73
- @bonnie.followees_count.should == 1
74
- @clyde.followers_count.should == 1
77
+ @alec.follow(@clyde)
78
+ @clyde.followers_count.should == 2
79
+ @bonnie.followers_count.should == 0
75
80
 
76
- @alec.follow(@clyde)
77
- @clyde.followers_count.should == 2
78
- @bonnie.followers_count.should == 0
81
+ @alec.unfollow(@clyde)
82
+ @alec.followees_count.should == 0
83
+ @clyde.followers_count.should == 1
79
84
 
80
- @alec.unfollow(@clyde)
81
- @alec.followees_count.should == 0
82
- @clyde.followers_count.should == 1
85
+ @bonnie.unfollow(@clyde)
86
+ @bonnie.followees_count.should == 0
87
+ @clyde.followers_count.should == 0
88
+ end
83
89
 
84
- @bonnie.unfollow(@clyde)
85
- @bonnie.followees_count.should == 0
86
- @clyde.followers_count.should == 0
87
- end
90
+ it "should allow to count followees by model" do
91
+ @alec.follow(@gang)
92
+ @alec.followees_count.should == 1
93
+ @alec.followees_count_by_model(Group).should == 1
88
94
 
89
- it "should list all followers" do
90
- @bonnie.follow(@clyde)
91
- # @clyde.all_followers.should == [@bonnie] # spec has an error on last #all_followers when this is called
95
+ @alec.follow(@clyde)
96
+ @alec.followees_count.should == 2
97
+ @alec.followees_count_by_model(Group).should == 1
98
+ end
92
99
 
93
- @alec.follow(@clyde)
94
- @clyde.all_followers.should == [@bonnie, @alec]
95
- end
100
+ it "should also allow to count followees by model with dynamic method" do
101
+ @alec.follow(@gang)
102
+ @alec.follow(@clyde)
96
103
 
97
- it "should list all followee" do
98
- @bonnie.follow(@clyde)
99
- # @bonnie.all_followees.should == [@clyde] # spec has an error on last #all_followees when this is called
104
+ @alec.group_followees_count.should == 1
105
+ end
100
106
 
101
- @bonnie.follow(@gang)
102
- @bonnie.all_followees.should == [@clyde, @gang]
107
+ it "should allow to count followers by model" do
108
+ @just_another_user.follow(@gang)
109
+ @gang.followers_count.should == 1
110
+ @gang.followers_count_by_model(OtherUser).should == 1
111
+
112
+ @alec.follow(@gang)
113
+ @gang.followers_count.should == 2
114
+ @gang.followers_count_by_model(OtherUser).should == 1
115
+ end
116
+
117
+ it "should also allow to count followers by model with dynamic method" do
118
+ @just_another_user.follow(@gang)
119
+ @alec.follow(@gang)
120
+
121
+ @gang.user_followers_count.should == 1
122
+ end
103
123
  end
104
124
 
105
- it "should have common followers" do
106
- @bonnie.follow(@clyde)
107
- @bonnie.follow(@gang)
125
+ describe "listing stuff" do
126
+ it "should list all followers" do
127
+ @bonnie.follow(@clyde)
128
+ # @clyde.all_followers.should == [@bonnie] # spec has an error on last #all_followers when this is called
108
129
 
109
- @gang.common_followers_with(@clyde).should == [@bonnie]
130
+ @alec.follow(@clyde)
131
+ @clyde.all_followers.should == [@bonnie, @alec]
132
+ end
110
133
 
111
- @alec.follow(@clyde)
112
- @alec.follow(@gang)
134
+ it "should list all followers by model" do
135
+ @bonnie.follow(@gang)
136
+ @just_another_user.follow(@gang)
113
137
 
114
- @clyde.common_followers_with(@gang).should == [@bonnie, @alec]
115
- end
138
+ @gang.all_followers.should == [@bonnie, @just_another_user]
139
+ @gang.all_followers_by_model(User).should == [@bonnie]
140
+ end
116
141
 
117
- it "should have common followees" do
118
- @bonnie.follow(@gang)
119
- @alec.follow(@gang)
142
+ it "should list all followers by model with dynamic method" do
143
+ @bonnie.follow(@gang)
144
+ @just_another_user.follow(@gang)
120
145
 
121
- @alec.common_followees_with(@bonnie).should == [@gang]
146
+ @gang.all_user_followers(User).should == [@bonnie]
147
+ end
122
148
 
123
- @bonnie.follow(@clyde)
124
- @alec.follow(@clyde)
149
+ it "should list all followees" do
150
+ @bonnie.follow(@clyde)
151
+ # @bonnie.all_followees.should == [@clyde] # spec has an error on last #all_followees when this is called
152
+
153
+ @bonnie.follow(@gang)
154
+ @bonnie.all_followees.should == [@clyde, @gang]
155
+ end
156
+
157
+ it "should list all followees by model" do
158
+ @bonnie.follow(@gang)
159
+ @bonnie.follow(@clyde)
160
+
161
+ @bonnie.all_followees.should == [@gang, @clyde]
162
+ @bonnie.all_followees_by_model(User).should == [@clyde]
163
+ end
164
+
165
+ it "should list all followees by model with dynamic method" do
166
+ @bonnie.follow(@gang)
167
+ @bonnie.follow(@clyde)
168
+
169
+ @bonnie.all_user_followees.should == [@clyde]
170
+ end
171
+
172
+ it "should have common followers" do
173
+ @bonnie.follow(@clyde)
174
+ @bonnie.follow(@gang)
125
175
 
126
- @bonnie.common_followees_with(@alec).should == [@gang, @clyde]
176
+ @gang.common_followers_with(@clyde).should == [@bonnie]
177
+
178
+ @alec.follow(@clyde)
179
+ @alec.follow(@gang)
180
+
181
+ @clyde.common_followers_with(@gang).should == [@bonnie, @alec]
182
+ end
183
+
184
+ it "should have common followees" do
185
+ @bonnie.follow(@gang)
186
+ @alec.follow(@gang)
187
+
188
+ @alec.common_followees_with(@bonnie).should == [@gang]
189
+
190
+ @bonnie.follow(@clyde)
191
+ @alec.follow(@clyde)
192
+
193
+ @bonnie.common_followees_with(@alec).should == [@gang, @clyde]
194
+ end
127
195
  end
128
196
 
129
- # Duh... this is a useless spec... Hrmn...
130
- it "should respond on callbacks" do
131
- @bonnie.respond_to?('after_follow').should be_true
132
- @bonnie.respond_to?('after_unfollowed_by').should be_true
133
- @bonnie.respond_to?('before_follow').should be_false
197
+ describe "callback stuff" do
198
+ # Duh... this is a useless spec... Hrmn...
199
+ it "should respond on callbacks" do
200
+ @bonnie.respond_to?('after_follow').should be_true
201
+ @bonnie.respond_to?('after_unfollowed_by').should be_true
202
+ @bonnie.respond_to?('before_follow').should be_false
134
203
 
135
- @gang.respond_to?('before_followed_by').should be_true
136
- @gang.respond_to?('after_followed_by').should be_false
204
+ @gang.respond_to?('before_followed_by').should be_true
205
+ @gang.respond_to?('after_followed_by').should be_false
206
+ end
137
207
  end
208
+
138
209
  end
139
210
  end
metadata CHANGED
@@ -1,72 +1,67 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: mongoid_follow
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.2
4
5
  prerelease:
5
- version: 0.2.1
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Alec Guintu
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-11-17 00:00:00 +08:00
14
- default_executable:
15
- dependencies:
16
- - !ruby/object:Gem::Dependency
12
+ date: 2012-03-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
17
15
  name: mongoid
18
- prerelease: false
19
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70284082589660 !ruby/object:Gem::Requirement
20
17
  none: false
21
- requirements:
22
- - - ">="
23
- - !ruby/object:Gem::Version
24
- version: "0"
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
25
22
  type: :runtime
26
- version_requirements: *id001
27
- - !ruby/object:Gem::Dependency
28
- name: bson_ext
29
23
  prerelease: false
30
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *70284082589660
25
+ - !ruby/object:Gem::Dependency
26
+ name: bson_ext
27
+ requirement: &70284082589180 !ruby/object:Gem::Requirement
31
28
  none: false
32
- requirements:
33
- - - ">="
34
- - !ruby/object:Gem::Version
35
- version: "0"
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
36
33
  type: :runtime
37
- version_requirements: *id002
38
- - !ruby/object:Gem::Dependency
39
- name: database_cleaner
40
34
  prerelease: false
41
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *70284082589180
36
+ - !ruby/object:Gem::Dependency
37
+ name: database_cleaner
38
+ requirement: &70284082588680 !ruby/object:Gem::Requirement
42
39
  none: false
43
- requirements:
44
- - - ">="
45
- - !ruby/object:Gem::Version
46
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
47
44
  type: :development
48
- version_requirements: *id003
49
- - !ruby/object:Gem::Dependency
50
- name: rspec
51
45
  prerelease: false
52
- requirement: &id004 !ruby/object:Gem::Requirement
46
+ version_requirements: *70284082588680
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70284082588160 !ruby/object:Gem::Requirement
53
50
  none: false
54
- requirements:
55
- - - ">="
56
- - !ruby/object:Gem::Version
57
- version: "0"
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
58
55
  type: :development
59
- version_requirements: *id004
60
- description: " Gem to add basic \"follow\" features if you're using rails3 with mongoid "
61
- email:
56
+ prerelease: false
57
+ version_requirements: *70284082588160
58
+ description: ! ' Gem to add basic "follow" features if you''re using rails3 with mongoid '
59
+ email:
62
60
  - animerei12@gmail.com
63
61
  executables: []
64
-
65
62
  extensions: []
66
-
67
63
  extra_rdoc_files: []
68
-
69
- files:
64
+ files:
70
65
  - .gitignore
71
66
  - Gemfile
72
67
  - LICENSE.txt
@@ -76,42 +71,41 @@ files:
76
71
  - lib/mongoid_follow.rb
77
72
  - lib/mongoid_follow/followee.rb
78
73
  - lib/mongoid_follow/follower.rb
74
+ - lib/mongoid_follow/helper.rb
79
75
  - lib/mongoid_follow/version.rb
80
76
  - mongoid_follow.gemspec
81
77
  - spec/models/group.rb
78
+ - spec/models/other_user.rb
82
79
  - spec/models/user.rb
83
80
  - spec/spec_helper.rb
84
81
  - spec/specs/follow_spec.rb
85
- has_rdoc: true
86
82
  homepage: https://github.com/alecguintu/mongoid_follow
87
83
  licenses: []
88
-
89
84
  post_install_message:
90
85
  rdoc_options: []
91
-
92
- require_paths:
86
+ require_paths:
93
87
  - lib
94
- required_ruby_version: !ruby/object:Gem::Requirement
88
+ required_ruby_version: !ruby/object:Gem::Requirement
95
89
  none: false
96
- requirements:
97
- - - ">="
98
- - !ruby/object:Gem::Version
99
- version: "0"
100
- required_rubygems_version: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
95
  none: false
102
- requirements:
103
- - - ">="
104
- - !ruby/object:Gem::Version
105
- version: "0"
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
106
100
  requirements: []
107
-
108
101
  rubyforge_project: mongoid_follow
109
- rubygems_version: 1.6.2
102
+ rubygems_version: 1.8.17
110
103
  signing_key:
111
104
  specification_version: 3
112
105
  summary: Add basic "follow" features to rails3 + mongoid
113
- test_files:
106
+ test_files:
114
107
  - spec/models/group.rb
108
+ - spec/models/other_user.rb
115
109
  - spec/models/user.rb
116
110
  - spec/spec_helper.rb
117
111
  - spec/specs/follow_spec.rb