mongoid_follow 0.2.1 → 0.2.2

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/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