party_boy 0.1.2 → 0.1.3
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 +31 -5
- data/VERSION +1 -1
- data/lib/party_boy.rb +30 -29
- data/party_boy.gemspec +2 -2
- data/spec/party_boy_spec.rb +82 -3
- metadata +2 -2
data/README.rdoc
CHANGED
@@ -54,7 +54,7 @@ To retrieve a set of models based on the relationships, use:
|
|
54
54
|
|
55
55
|
==== STI
|
56
56
|
|
57
|
-
STI is also handled by party_boy. The relationship is always stored using the super-most class. However, relationships to inheriting classes can also be retrieved. Do so by passing in the type
|
57
|
+
STI is also handled by party_boy. The relationship is always stored using the super-most class. However, relationships to inheriting classes can also be retrieved. Do so by passing in the type:
|
58
58
|
|
59
59
|
class Quarterback < User; end
|
60
60
|
class Cheerleader < User; end
|
@@ -62,11 +62,14 @@ STI is also handled by party_boy. The relationship is always stored using the su
|
|
62
62
|
|
63
63
|
In string form
|
64
64
|
a.followers('users')
|
65
|
-
|
66
|
-
|
65
|
+
=> [#<User id: 1, created_at: "2010-01-27 01:09:42", updated_at: "2010-01-27 01:09:42">]
|
66
|
+
a.following(quarterbacks)
|
67
|
+
=> [#<Quarterback id: 3, created_at: "2010-01-27 01:09:42", updated_at: "2010-01-27 01:09:42">]
|
67
68
|
Or in class form
|
68
69
|
a.followers(User)
|
69
|
-
|
70
|
+
=> [#<User id: 1, created_at: "2010-01-27 01:09:42", updated_at: "2010-01-27 01:09:42">]
|
71
|
+
b.following(Quarterback)
|
72
|
+
=> [#<Quarterback id: 3, created_at: "2010-01-27 01:09:42", updated_at: "2010-01-27 01:09:42">]
|
70
73
|
|
71
74
|
==== STI - part deux
|
72
75
|
|
@@ -81,8 +84,31 @@ On top of accessing relationships through followers / following methods, party_b
|
|
81
84
|
|
82
85
|
=== acts_as_friend
|
83
86
|
|
84
|
-
|
87
|
+
To allow two models to become friends (requiring acceptance), add acts_as_friend to both. Now you can create a relationship between the two models by:
|
88
|
+
|
89
|
+
class Bob < ActiveRecord::Base
|
90
|
+
acts_as_friend
|
91
|
+
end
|
92
|
+
|
93
|
+
class Joe < ActiveRecord::Base
|
94
|
+
acts_as_friend
|
95
|
+
end
|
96
|
+
|
97
|
+
b = Bob.create
|
98
|
+
j = Joe.create
|
99
|
+
|
100
|
+
b.request_friendship(j)
|
101
|
+
|
102
|
+
b.pending?(j)
|
103
|
+
=> true
|
104
|
+
|
105
|
+
b.outgoing_friend_requests # or j.incoming_friend_requests
|
106
|
+
=> [#<Relationship id: 1, :requestor_id: 1, :requestor_type: 'Bob', requestee_id: 1, requestee_type: 'Joe', restricted: true>]
|
107
|
+
|
108
|
+
j.accept_friendship(b)
|
85
109
|
|
110
|
+
b.friends
|
111
|
+
=> [#<Joe id: 1>]
|
86
112
|
|
87
113
|
== Copyright
|
88
114
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.3
|
data/lib/party_boy.rb
CHANGED
@@ -40,26 +40,18 @@ module Party
|
|
40
40
|
module RelateableInstanceMethods
|
41
41
|
|
42
42
|
private
|
43
|
-
|
43
|
+
|
44
44
|
# should be able to pass a class, string, or object and get back the super-most class (before activerecord)
|
45
45
|
def super_class_name(obj = self)
|
46
|
-
obj = (obj.class == Class && obj || obj.class == String && obj.constantize || obj.class)
|
47
|
-
if obj.superclass != ActiveRecord::Base
|
48
|
-
super_class_name(obj.superclass)
|
49
|
-
else
|
50
|
-
obj.name
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def super_class_names(obj = self)
|
55
46
|
if obj.nil?
|
56
47
|
return nil
|
57
48
|
end
|
58
|
-
|
49
|
+
|
50
|
+
obj = (obj.class == Class && obj || obj.class == String && obj.classify.constantize || obj.class)
|
59
51
|
if obj.superclass != ActiveRecord::Base
|
60
|
-
|
52
|
+
super_class_name(obj.superclass)
|
61
53
|
else
|
62
|
-
|
54
|
+
obj.name
|
63
55
|
end
|
64
56
|
end
|
65
57
|
|
@@ -112,11 +104,10 @@ module Party
|
|
112
104
|
end
|
113
105
|
|
114
106
|
def followers(type = nil)
|
115
|
-
|
116
|
-
|
117
|
-
exact_class = type.first
|
107
|
+
super_class = super_class_name(type)
|
108
|
+
exact_class = type && type.to_s.classify
|
118
109
|
results = relationships_from(super_class)
|
119
|
-
if super_class != exact_class
|
110
|
+
if super_class && exact_class && super_class != exact_class
|
120
111
|
results.collect{|r| r.requestor.class.name == exact_class && r.requestor || nil}.compact
|
121
112
|
else
|
122
113
|
results.collect{|r| r.requestor}
|
@@ -125,11 +116,10 @@ module Party
|
|
125
116
|
end
|
126
117
|
|
127
118
|
def following(type = nil)
|
128
|
-
|
129
|
-
|
130
|
-
exact_class = type.first
|
119
|
+
super_class = super_class_name(type)
|
120
|
+
exact_class = type && type.to_s.classify
|
131
121
|
results = relationships_to(super_class)
|
132
|
-
if super_class != exact_class
|
122
|
+
if super_class && exact_class && super_class != exact_class
|
133
123
|
results.collect{|r| r.requestee.class.name == exact_class && r.requestee || nil}.compact
|
134
124
|
else
|
135
125
|
results.collect{|r| r.requestee}
|
@@ -143,12 +133,11 @@ module Party
|
|
143
133
|
def method_missing(method, *args)
|
144
134
|
case method.id2name
|
145
135
|
when /^(.+)ss_followers$/
|
146
|
-
#
|
147
|
-
followers(super_class_names("#{$1.classify}ss"))
|
136
|
+
followers("#{$1}ss".classify)
|
148
137
|
when /^(.+)s_followers$/, /^(.+)_followers$/
|
149
|
-
followers(
|
138
|
+
followers($1.classify)
|
150
139
|
when /^following_(.+)$/
|
151
|
-
following(
|
140
|
+
following($1.classify)
|
152
141
|
else
|
153
142
|
super
|
154
143
|
end
|
@@ -184,7 +173,7 @@ module Party
|
|
184
173
|
self.incoming_friendships.unaccepted.all
|
185
174
|
end
|
186
175
|
|
187
|
-
def
|
176
|
+
def friends_with?(something)
|
188
177
|
arr = something && [self.id, super_class_name, super_class_name(something), something.id]
|
189
178
|
arr && Relationship.accepted.count(:conditions => [(['(requestor_id = ? AND requestor_type = ? AND requestee_type = ? AND requestee_id = ?)']*2).join(' OR '), arr, arr.reverse].flatten) > 0
|
190
179
|
end
|
@@ -201,14 +190,14 @@ module Party
|
|
201
190
|
|
202
191
|
def request_friendship(friendship_or_something)
|
203
192
|
rel = relationship_from(friendship_or_something)
|
204
|
-
rel.nil? && Relationship.create(:requestor => self, :requestee => friendship_or_something, :restricted => true) || rel.update_attributes(:restricted => false)
|
193
|
+
rel.nil? && Relationship.create(:requestor => self, :requestee => friendship_or_something, :restricted => true) || (rel.requestee == self && rel.update_attributes(:restricted => false))
|
205
194
|
end
|
206
195
|
|
207
196
|
def deny_friendship(friendship_or_something)
|
208
197
|
(rel = relationship_from(friendship_or_something)) && rel.destroy
|
209
198
|
end
|
210
199
|
|
211
|
-
|
200
|
+
[:reject_friendship, :destroy_friendship, :leave_friendship].each{|key| alias_method key, :deny_friendship}
|
212
201
|
alias_method :accept_friendship, :request_friendship
|
213
202
|
|
214
203
|
private
|
@@ -224,4 +213,16 @@ module Party
|
|
224
213
|
end
|
225
214
|
end
|
226
215
|
end
|
227
|
-
end
|
216
|
+
end
|
217
|
+
|
218
|
+
class String
|
219
|
+
def classify
|
220
|
+
if self[(self.length - 2)...self.length] == 'ss'
|
221
|
+
"#{self[0...(self.length-2)].classify}ss"
|
222
|
+
else
|
223
|
+
super
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
::ActiveRecord::Base.send :include, Party::Boy
|
data/party_boy.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{party_boy}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.3"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Mike Nelson"]
|
12
|
-
s.date = %q{2010-01-
|
12
|
+
s.date = %q{2010-01-29}
|
13
13
|
s.description = %q{Models relationships between AR models. Allows you to follow, friend, and block other AR's. Consists of two mixins: acts_as_followable and acts_as_friend. These options allow an AR to inherit either a twitter-like follower system or a facebook-like friend system.}
|
14
14
|
s.email = %q{mdnelson30@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/spec/party_boy_spec.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
2
|
|
3
3
|
|
4
|
-
describe "
|
4
|
+
describe "party_boy" do
|
5
5
|
|
6
6
|
it "should integrate follower methods properly" do
|
7
7
|
%w(followers following following? followed_by?).each do |method|
|
@@ -39,7 +39,7 @@ describe "PartyBoy" do
|
|
39
39
|
|
40
40
|
end
|
41
41
|
|
42
|
-
describe "
|
42
|
+
describe "party_boy -- follower" do
|
43
43
|
it "should generate relationships and return proper counts" do
|
44
44
|
a = FollowerClass.create
|
45
45
|
b = FollowerClass.create
|
@@ -126,7 +126,7 @@ describe "PartyBoy -- Follower" do
|
|
126
126
|
|
127
127
|
class User < FollowerClass; end
|
128
128
|
class Business < FollowerClass; end
|
129
|
-
|
129
|
+
class Program < FollowerClass; end
|
130
130
|
|
131
131
|
it "should handle STI properly" do
|
132
132
|
u = User.create
|
@@ -138,6 +138,26 @@ describe "PartyBoy -- Follower" do
|
|
138
138
|
u.following.first.class.name.should eql('Business')
|
139
139
|
end
|
140
140
|
|
141
|
+
it "should handle passed data types properly" do
|
142
|
+
u = User.create
|
143
|
+
b = Business.create
|
144
|
+
p = Program.create
|
145
|
+
|
146
|
+
u.follow(b)
|
147
|
+
u.follow(p)
|
148
|
+
|
149
|
+
u.following(Business).should eql([b])
|
150
|
+
u.following(Program).should eql([p])
|
151
|
+
u.following.size.should eql(2)
|
152
|
+
|
153
|
+
u.following('Business').should eql([b])
|
154
|
+
u.following('businesses').should eql([b])
|
155
|
+
u.following('Program').should eql([p])
|
156
|
+
u.following('programs').should eql([p])
|
157
|
+
|
158
|
+
u.following.size.should eql(2)
|
159
|
+
end
|
160
|
+
|
141
161
|
it "should handle method_missing properly" do
|
142
162
|
u = User.create
|
143
163
|
b = Business.create
|
@@ -165,3 +185,62 @@ describe "PartyBoy -- Follower" do
|
|
165
185
|
|
166
186
|
end
|
167
187
|
|
188
|
+
|
189
|
+
describe "party_boy - friend" do
|
190
|
+
|
191
|
+
it "should make and break friendships properly" do
|
192
|
+
a = FriendClass.create
|
193
|
+
b = FriendClass.create
|
194
|
+
|
195
|
+
r = a.request_friendship(b)
|
196
|
+
r.accepted?.should be_false
|
197
|
+
|
198
|
+
b.incoming_friend_requests.size.should eql(1)
|
199
|
+
a.outgoing_friend_requests.size.should eql(1)
|
200
|
+
|
201
|
+
b.accept_friendship(a)
|
202
|
+
|
203
|
+
a.friends.should eql([b])
|
204
|
+
b.friends.should eql([a])
|
205
|
+
|
206
|
+
a.leave_friendship(b)
|
207
|
+
|
208
|
+
a.friends.empty?.should be_true
|
209
|
+
b.friends.empty?.should be_true
|
210
|
+
|
211
|
+
a.request_friendship(b)
|
212
|
+
b.request_friendship(a)
|
213
|
+
|
214
|
+
a.friends.should eql([b])
|
215
|
+
b.friends.should eql([a])
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should return proper counts and states" do
|
219
|
+
a = FriendClass.new
|
220
|
+
b = FriendClass.new
|
221
|
+
c = FriendClass.new
|
222
|
+
d = FriendClass.new
|
223
|
+
|
224
|
+
a.request_friendship(b)
|
225
|
+
a.request_friendship(c)
|
226
|
+
b.request_friendship(c)
|
227
|
+
|
228
|
+
a.pending?(b).should be_true
|
229
|
+
a.pending?(c).should be_true
|
230
|
+
a.pending?(d).should be_false
|
231
|
+
|
232
|
+
b.accept_friendship(a)
|
233
|
+
c.accept_friendship(a)
|
234
|
+
c.reject_friendship(b)
|
235
|
+
|
236
|
+
a.friend_count.should eql(2)
|
237
|
+
b.friend_count.should eql(1)
|
238
|
+
c.friend_count.should eql(1)
|
239
|
+
|
240
|
+
a.friends_with?(b).should be_true
|
241
|
+
c.friends_with?(a).should be_true
|
242
|
+
b.friends_with?(c).should be_false
|
243
|
+
end
|
244
|
+
|
245
|
+
end
|
246
|
+
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: party_boy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mike Nelson
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-01-
|
12
|
+
date: 2010-01-29 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|