amistad 0.6.0 → 0.7.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/CHANGELOG +5 -0
- data/README.markdown +13 -10
- data/amistad.gemspec +4 -2
- data/lib/amistad.rb +3 -0
- data/lib/amistad/active_record/friend_model.rb +136 -0
- data/lib/amistad/active_record/friendship_model.rb +50 -0
- data/lib/amistad/friend_model.rb +11 -128
- data/lib/amistad/friendship_model.rb +7 -42
- data/lib/amistad/mongoid/friend_model.rb +180 -0
- data/lib/amistad/version.rb +1 -1
- data/spec/activerecord_friend_model_spec.rb +9 -0
- data/spec/{friendship_model_spec.rb → activerecord_friendship_model_spec.rb} +2 -2
- data/spec/activerecord_spec_helper.rb +33 -0
- data/spec/mongoid_friend_model_spec.rb +21 -0
- data/spec/mongoid_spec_helper.rb +11 -0
- data/spec/spec_helper.rb +1 -31
- data/spec/{friend_model_spec.rb → support/friend_examples.rb} +18 -20
- metadata +43 -34
data/CHANGELOG
CHANGED
data/README.markdown
CHANGED
@@ -1,28 +1,24 @@
|
|
1
1
|
# amistad #
|
2
2
|
|
3
|
-
Amistad adds friendships management into a rails 3.0 application.
|
3
|
+
Amistad adds friendships management into a rails 3.0 application. it supports ActiveRecord and Mongoid.
|
4
4
|
|
5
5
|
## Installation ##
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
gem install amistad
|
10
|
-
|
11
|
-
Then in your Gemfile add the following line :
|
7
|
+
Add the following line in your Gemfile:
|
12
8
|
|
13
9
|
gem 'amistad'
|
14
10
|
|
15
|
-
|
11
|
+
Then run:
|
16
12
|
|
17
13
|
bundle install
|
18
14
|
|
19
15
|
## Usage ##
|
20
16
|
|
21
|
-
|
17
|
+
If you are using ActiveRecord, you need to generate a friendship model. Amistad has a generator for this task :
|
22
18
|
|
23
19
|
rails generate amistad:install
|
24
20
|
|
25
|
-
This
|
21
|
+
This command creates a new model called __friendship__ in *'app/models'* :
|
26
22
|
|
27
23
|
class Friendship < ActiveRecord::Base
|
28
24
|
include Amistad::FriendshipModel
|
@@ -32,12 +28,19 @@ It also creates a new migration for the friendship model so don't forget to migr
|
|
32
28
|
|
33
29
|
rake db:migrate
|
34
30
|
|
35
|
-
|
31
|
+
If you are using Mongoig, you don't need a friendship model. Finally, activate __amistad__ in your user model :
|
36
32
|
|
37
33
|
class User < ActiveRecord::Base
|
38
34
|
include Amistad::FriendModel
|
39
35
|
end
|
40
36
|
|
37
|
+
or :
|
38
|
+
|
39
|
+
class User
|
40
|
+
include Mongoid::Document
|
41
|
+
include Amistad::FriendModel
|
42
|
+
end
|
43
|
+
|
41
44
|
## Friendships management ##
|
42
45
|
|
43
46
|
### Creating friendships ###
|
data/amistad.gemspec
CHANGED
@@ -15,9 +15,11 @@ Gem::Specification.new do |s|
|
|
15
15
|
s.rubyforge_project = "amistad"
|
16
16
|
|
17
17
|
s.add_development_dependency "bundler", "~>1.0.7"
|
18
|
-
s.add_development_dependency "rspec", "~> 2.
|
19
|
-
s.add_development_dependency "activerecord", "~> 3.0.
|
18
|
+
s.add_development_dependency "rspec", "~> 2.5.0"
|
19
|
+
s.add_development_dependency "activerecord", "~> 3.0.4"
|
20
20
|
s.add_development_dependency "sqlite3-ruby", "1.3.2"
|
21
|
+
s.add_development_dependency "mongoid", "~> 2.0.0.rc.7"
|
22
|
+
s.add_development_dependency "bson_ext", "~> 1.2"
|
21
23
|
|
22
24
|
s.files = `git ls-files`.split("\n")
|
23
25
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
data/lib/amistad.rb
CHANGED
@@ -0,0 +1,136 @@
|
|
1
|
+
module Amistad
|
2
|
+
module ActiveRecord
|
3
|
+
module FriendModel
|
4
|
+
def self.included(receiver)
|
5
|
+
receiver.class_exec do
|
6
|
+
include InstanceMethods
|
7
|
+
|
8
|
+
has_many :friendships
|
9
|
+
|
10
|
+
has_many :pending_invited,
|
11
|
+
:through => :friendships,
|
12
|
+
:source => :friend,
|
13
|
+
:conditions => { :'friendships.pending' => true, :'friendships.blocker_id' => nil }
|
14
|
+
|
15
|
+
has_many :invited,
|
16
|
+
:through => :friendships,
|
17
|
+
:source => :friend,
|
18
|
+
:conditions => { :'friendships.pending' => false, :'friendships.blocker_id' => nil }
|
19
|
+
|
20
|
+
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
|
21
|
+
|
22
|
+
has_many :pending_invited_by,
|
23
|
+
:through => :inverse_friendships,
|
24
|
+
:source => :user,
|
25
|
+
:conditions => { :'friendships.pending' => true, :'friendships.blocker_id' => nil }
|
26
|
+
|
27
|
+
has_many :invited_by,
|
28
|
+
:through => :inverse_friendships,
|
29
|
+
:source => :user,
|
30
|
+
:conditions => { :'friendships.pending' => false, :'friendships.blocker_id' => nil }
|
31
|
+
|
32
|
+
has_many :blocked_friendships, :class_name => "Friendship", :foreign_key => "blocker_id"
|
33
|
+
|
34
|
+
has_many :blockades,
|
35
|
+
:through => :blocked_friendships,
|
36
|
+
:source => :friend,
|
37
|
+
:conditions => "friend_id <> blocker_id"
|
38
|
+
|
39
|
+
has_many :blockades_by,
|
40
|
+
:through => :blocked_friendships,
|
41
|
+
:source => :user,
|
42
|
+
:conditions => "user_id <> blocker_id"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
module InstanceMethods
|
47
|
+
# suggest a user to become a friend. If the operation succeeds, the method returns true, else false
|
48
|
+
def invite(user)
|
49
|
+
return false if user == self || find_any_friendship_with(user)
|
50
|
+
Friendship.new(:user_id => self.id, :friend_id => user.id).save
|
51
|
+
end
|
52
|
+
|
53
|
+
# approve a friendship invitation. If the operation succeeds, the method returns true, else false
|
54
|
+
def approve(user)
|
55
|
+
friendship = find_any_friendship_with(user)
|
56
|
+
return false if friendship.nil? || invited?(user)
|
57
|
+
friendship.update_attribute(:pending, false)
|
58
|
+
end
|
59
|
+
|
60
|
+
# deletes a friendship
|
61
|
+
def remove_friendship(user)
|
62
|
+
friendship = find_any_friendship_with(user)
|
63
|
+
return false if friendship.nil?
|
64
|
+
friendship.destroy && friendship.destroyed?
|
65
|
+
end
|
66
|
+
|
67
|
+
# returns the list of approved friends
|
68
|
+
def friends
|
69
|
+
self.invited(true) + self.invited_by(true)
|
70
|
+
end
|
71
|
+
|
72
|
+
# blocks a friendship
|
73
|
+
def block(user)
|
74
|
+
friendship = find_any_friendship_with(user)
|
75
|
+
return false if friendship.nil? || !friendship.can_block?(self)
|
76
|
+
friendship.update_attribute(:blocker, self)
|
77
|
+
end
|
78
|
+
|
79
|
+
# unblocks a friendship
|
80
|
+
def unblock(user)
|
81
|
+
friendship = find_any_friendship_with(user)
|
82
|
+
return false if friendship.nil? || !friendship.can_unblock?(self)
|
83
|
+
friendship.update_attribute(:blocker, nil)
|
84
|
+
end
|
85
|
+
|
86
|
+
# returns the list of blocked friends
|
87
|
+
def blocked
|
88
|
+
self.blockades(true) + self.blockades_by(true)
|
89
|
+
end
|
90
|
+
|
91
|
+
# checks if a user is blocked
|
92
|
+
def blocked?(user)
|
93
|
+
blocked.include?(user)
|
94
|
+
end
|
95
|
+
|
96
|
+
# checks if a user is a friend
|
97
|
+
def friend_with?(user)
|
98
|
+
friends.include?(user)
|
99
|
+
end
|
100
|
+
|
101
|
+
# checks if a current user is connected to given user
|
102
|
+
def connected_with?(user)
|
103
|
+
find_any_friendship_with(user).present?
|
104
|
+
end
|
105
|
+
|
106
|
+
# checks if a current user received invitation from given user
|
107
|
+
def invited_by?(user)
|
108
|
+
friendship = find_any_friendship_with(user)
|
109
|
+
return false if friendship.nil?
|
110
|
+
friendship.user == user
|
111
|
+
end
|
112
|
+
|
113
|
+
# checks if a current user invited given user
|
114
|
+
def invited?(user)
|
115
|
+
friendship = find_any_friendship_with(user)
|
116
|
+
return false if friendship.nil?
|
117
|
+
friendship.friend == user
|
118
|
+
end
|
119
|
+
|
120
|
+
# return the list of the ones among its friends which are also friend with the given use
|
121
|
+
def common_friends_with(user)
|
122
|
+
self.friends & user.friends
|
123
|
+
end
|
124
|
+
|
125
|
+
# returns friendship with given user or nil
|
126
|
+
def find_any_friendship_with(user)
|
127
|
+
friendship = Friendship.where(:user_id => self.id, :friend_id => user.id).first
|
128
|
+
if friendship.nil?
|
129
|
+
friendship = Friendship.where(:user_id => user.id, :friend_id => self.id).first
|
130
|
+
end
|
131
|
+
friendship
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Amistad
|
2
|
+
module ActiveRecord
|
3
|
+
module FriendshipModel
|
4
|
+
def self.included(receiver)
|
5
|
+
receiver.class_exec do
|
6
|
+
include InstanceMethods
|
7
|
+
|
8
|
+
belongs_to :user
|
9
|
+
belongs_to :friend, :class_name => "User", :foreign_key => "friend_id"
|
10
|
+
belongs_to :blocker, :class_name => "User", :foreign_key => "blocker_id"
|
11
|
+
|
12
|
+
validates_presence_of :user_id, :friend_id
|
13
|
+
validates_uniqueness_of :friend_id, :scope => :user_id
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
# returns true if a friendship has been approved, else false
|
19
|
+
def approved?
|
20
|
+
!self.pending
|
21
|
+
end
|
22
|
+
|
23
|
+
# returns true if a friendship has not been approved, else false
|
24
|
+
def pending?
|
25
|
+
self.pending
|
26
|
+
end
|
27
|
+
|
28
|
+
# returns true if a friendship has been blocked, else false
|
29
|
+
def blocked?
|
30
|
+
self.blocker_id.present?
|
31
|
+
end
|
32
|
+
|
33
|
+
# returns true if a friendship has not beed blocked, else false
|
34
|
+
def active?
|
35
|
+
self.blocker_id.nil?
|
36
|
+
end
|
37
|
+
|
38
|
+
# returns true if a friendship can be blocked by given user
|
39
|
+
def can_block?(user)
|
40
|
+
active? && (approved? || (pending? && self.friend == user))
|
41
|
+
end
|
42
|
+
|
43
|
+
# returns true if a friendship can be unblocked by given user
|
44
|
+
def can_unblock?(user)
|
45
|
+
blocked? && self.blocker == user
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/amistad/friend_model.rb
CHANGED
@@ -1,134 +1,17 @@
|
|
1
1
|
module Amistad
|
2
2
|
module FriendModel
|
3
3
|
def self.included(receiver)
|
4
|
-
receiver.
|
5
|
-
|
6
|
-
|
7
|
-
has_many :friendships
|
8
|
-
|
9
|
-
has_many :pending_invited,
|
10
|
-
:through => :friendships,
|
11
|
-
:source => :friend,
|
12
|
-
:conditions => { :'friendships.pending' => true, :'friendships.blocker_id' => nil }
|
13
|
-
|
14
|
-
has_many :invited,
|
15
|
-
:through => :friendships,
|
16
|
-
:source => :friend,
|
17
|
-
:conditions => { :'friendships.pending' => false, :'friendships.blocker_id' => nil }
|
18
|
-
|
19
|
-
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
|
20
|
-
|
21
|
-
has_many :pending_invited_by,
|
22
|
-
:through => :inverse_friendships,
|
23
|
-
:source => :user,
|
24
|
-
:conditions => { :'friendships.pending' => true, :'friendships.blocker_id' => nil }
|
25
|
-
|
26
|
-
has_many :invited_by,
|
27
|
-
:through => :inverse_friendships,
|
28
|
-
:source => :user,
|
29
|
-
:conditions => { :'friendships.pending' => false, :'friendships.blocker_id' => nil }
|
30
|
-
|
31
|
-
has_many :blocked_friendships, :class_name => "Friendship", :foreign_key => "blocker_id"
|
32
|
-
|
33
|
-
has_many :blockades,
|
34
|
-
:through => :blocked_friendships,
|
35
|
-
:source => :friend,
|
36
|
-
:conditions => "friend_id <> blocker_id"
|
37
|
-
|
38
|
-
has_many :blockades_by,
|
39
|
-
:through => :blocked_friendships,
|
40
|
-
:source => :user,
|
41
|
-
:conditions => "user_id <> blocker_id"
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
module InstanceMethods
|
46
|
-
# suggest a user to become a friend. If the operation succeeds, the method returns true, else false
|
47
|
-
def invite(user)
|
48
|
-
return false if user == self || find_any_friendship_with(user)
|
49
|
-
Friendship.new(:user_id => self.id, :friend_id => user.id).save
|
50
|
-
end
|
51
|
-
|
52
|
-
# approve a friendship invitation. If the operation succeeds, the method returns true, else false
|
53
|
-
def approve(user)
|
54
|
-
friendship = find_any_friendship_with(user)
|
55
|
-
return false if friendship.nil? || invited?(user)
|
56
|
-
friendship.update_attribute(:pending, false)
|
57
|
-
end
|
58
|
-
|
59
|
-
# deletes a friendship
|
60
|
-
def remove(user)
|
61
|
-
friendship = find_any_friendship_with(user)
|
62
|
-
return false if friendship.nil?
|
63
|
-
friendship.destroy && friendship.destroyed?
|
64
|
-
end
|
65
|
-
|
66
|
-
# returns the list of approved friends
|
67
|
-
def friends
|
68
|
-
self.invited(true) + self.invited_by(true)
|
69
|
-
end
|
70
|
-
|
71
|
-
# blocks a friendship
|
72
|
-
def block(user)
|
73
|
-
friendship = find_any_friendship_with(user)
|
74
|
-
return false if friendship.nil? || !friendship.can_block?(self)
|
75
|
-
friendship.update_attribute(:blocker, self)
|
76
|
-
end
|
77
|
-
|
78
|
-
# unblocks a friendship
|
79
|
-
def unblock(user)
|
80
|
-
friendship = find_any_friendship_with(user)
|
81
|
-
return false if friendship.nil? || !friendship.can_unblock?(self)
|
82
|
-
friendship.update_attribute(:blocker, nil)
|
83
|
-
end
|
84
|
-
|
85
|
-
# returns the list of blocked friends
|
86
|
-
def blocked
|
87
|
-
self.blockades(true) + self.blockades_by(true)
|
88
|
-
end
|
89
|
-
|
90
|
-
# checks if a user is blocked
|
91
|
-
def blocked?(user)
|
92
|
-
blocked.include?(user)
|
93
|
-
end
|
94
|
-
|
95
|
-
# checks if a user is a friend
|
96
|
-
def friend_with?(user)
|
97
|
-
friends.include?(user)
|
98
|
-
end
|
99
|
-
|
100
|
-
# checks if a current user is connected to given user
|
101
|
-
def connected_with?(user)
|
102
|
-
find_any_friendship_with(user).present?
|
103
|
-
end
|
104
|
-
|
105
|
-
# checks if a current user received invitation from given user
|
106
|
-
def invited_by?(user)
|
107
|
-
friendship = find_any_friendship_with(user)
|
108
|
-
return false if friendship.nil?
|
109
|
-
friendship.user == user
|
110
|
-
end
|
111
|
-
|
112
|
-
# checks if a current user invited given user
|
113
|
-
def invited?(user)
|
114
|
-
friendship = find_any_friendship_with(user)
|
115
|
-
return false if friendship.nil?
|
116
|
-
friendship.friend == user
|
117
|
-
end
|
118
|
-
|
119
|
-
# return the list of the ones among its friends which are also friend with the given use
|
120
|
-
def common_friends_with(user)
|
121
|
-
self.friends & user.friends
|
122
|
-
end
|
123
|
-
|
124
|
-
# returns friendship with given user or nil
|
125
|
-
def find_any_friendship_with(user)
|
126
|
-
friendship = Friendship.where(:user_id => self.id, :friend_id => user.id).first
|
127
|
-
if friendship.nil?
|
128
|
-
friendship = Friendship.where(:user_id => user.id, :friend_id => self.id).first
|
4
|
+
if receiver.ancestors.map(&:to_s).include?("ActiveRecord::Base")
|
5
|
+
receiver.class_exec do
|
6
|
+
include Amistad::ActiveRecord::FriendModel
|
129
7
|
end
|
130
|
-
|
8
|
+
elsif receiver.ancestors.map(&:to_s).include?("Mongoid::Document")
|
9
|
+
receiver.class_exec do
|
10
|
+
include Amistad::Mongoid::FriendModel
|
11
|
+
end
|
12
|
+
else
|
13
|
+
raise "Amistad only supports ActiveRecord and Mongoid"
|
131
14
|
end
|
132
|
-
end
|
15
|
+
end
|
133
16
|
end
|
134
|
-
end
|
17
|
+
end
|
@@ -1,48 +1,13 @@
|
|
1
1
|
module Amistad
|
2
2
|
module FriendshipModel
|
3
3
|
def self.included(receiver)
|
4
|
-
receiver.
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
validates_presence_of :user_id, :friend_id
|
12
|
-
validates_uniqueness_of :friend_id, :scope => :user_id
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
module InstanceMethods
|
17
|
-
# returns true if a friendship has been approved, else false
|
18
|
-
def approved?
|
19
|
-
!self.pending
|
20
|
-
end
|
21
|
-
|
22
|
-
# returns true if a friendship has not been approved, else false
|
23
|
-
def pending?
|
24
|
-
self.pending
|
25
|
-
end
|
26
|
-
|
27
|
-
# returns true if a friendship has been blocked, else false
|
28
|
-
def blocked?
|
29
|
-
self.blocker_id.present?
|
30
|
-
end
|
31
|
-
|
32
|
-
# returns true if a friendship has not beed blocked, else false
|
33
|
-
def active?
|
34
|
-
self.blocker_id.nil?
|
35
|
-
end
|
36
|
-
|
37
|
-
# returns true if a friendship can be blocked by given user
|
38
|
-
def can_block?(user)
|
39
|
-
active? && (approved? || (pending? && self.friend == user))
|
40
|
-
end
|
41
|
-
|
42
|
-
# returns true if a friendship can be unblocked by given user
|
43
|
-
def can_unblock?(user)
|
44
|
-
blocked? && self.blocker == user
|
4
|
+
if receiver.ancestors.map(&:to_s).include?("ActiveRecord::Base")
|
5
|
+
receiver.class_exec do
|
6
|
+
include Amistad::ActiveRecord::FriendshipModel
|
7
|
+
end
|
8
|
+
else
|
9
|
+
raise "Amistad only supports ActiveRecord and Mongoid"
|
45
10
|
end
|
46
11
|
end
|
47
12
|
end
|
48
|
-
end
|
13
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
module Amistad
|
2
|
+
module Mongoid
|
3
|
+
module FriendModel
|
4
|
+
def self.included(receiver)
|
5
|
+
receiver.class_exec do
|
6
|
+
include InstanceMethods
|
7
|
+
|
8
|
+
field :friend_ids, :type => Array, :default => []
|
9
|
+
field :inverse_friend_ids, :type => Array, :default => []
|
10
|
+
field :pending_friend_ids, :type => Array, :default => []
|
11
|
+
field :pending_inverse_friend_ids, :type => Array, :default => []
|
12
|
+
|
13
|
+
field :blocked_friend_ids, :type => Array, :default => []
|
14
|
+
field :blocked_inverse_friend_ids, :type => Array, :default => []
|
15
|
+
field :blocked_pending_friend_ids, :type => Array, :default => []
|
16
|
+
field :blocked_pending_inverse_friend_ids, :type => Array, :default => []
|
17
|
+
|
18
|
+
attr_accessible :friend_ids, :inverse_friend_ids, :pending_friend_ids, :pending_inverse_friend_ids, :blocked_friend_ids, :blocked_inverse_friend_ids, :blocked_pending_friend_ids, :blocked_pending_inverse_friend_ids
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
module InstanceMethods
|
23
|
+
# suggest a user to become a friend. If the operation succeeds, the method returns true, else false
|
24
|
+
def invite(user)
|
25
|
+
return false if friendshiped_with?(user) or user == self or blocked?(user)
|
26
|
+
pending_friend_ids << user.id
|
27
|
+
user.pending_inverse_friend_ids << self.id
|
28
|
+
self.save && user.save
|
29
|
+
end
|
30
|
+
|
31
|
+
# approve a friendship invitation. If the operation succeeds, the method returns true, else false
|
32
|
+
def approve(user)
|
33
|
+
return false unless pending_inverse_friend_ids.include?(user.id) && user.pending_friend_ids.include?(self.id)
|
34
|
+
pending_inverse_friend_ids.delete(user.id)
|
35
|
+
user.pending_friend_ids.delete(self.id)
|
36
|
+
inverse_friend_ids << user.id
|
37
|
+
user.friend_ids << self.id
|
38
|
+
self.save && user.save
|
39
|
+
end
|
40
|
+
|
41
|
+
# returns the list of approved friends
|
42
|
+
def friends
|
43
|
+
self.invited + self.invited_by
|
44
|
+
end
|
45
|
+
|
46
|
+
# return the list of invited friends
|
47
|
+
def invited
|
48
|
+
self.class.find(friend_ids)
|
49
|
+
end
|
50
|
+
|
51
|
+
# return the list of friends who invited
|
52
|
+
def invited_by
|
53
|
+
self.class.find(inverse_friend_ids)
|
54
|
+
end
|
55
|
+
|
56
|
+
# return the list of pending invited friends
|
57
|
+
def pending_invited
|
58
|
+
self.class.find(pending_friend_ids)
|
59
|
+
end
|
60
|
+
|
61
|
+
# return the list of pending friends who invited
|
62
|
+
def pending_invited_by
|
63
|
+
self.class.find(pending_inverse_friend_ids)
|
64
|
+
end
|
65
|
+
|
66
|
+
# return the list of the ones among its friends which are also friend with the given use
|
67
|
+
def common_friends_with(user)
|
68
|
+
self.friends & user.friends
|
69
|
+
end
|
70
|
+
|
71
|
+
# checks if a user is a friend
|
72
|
+
def friend_with?(user)
|
73
|
+
return false if user == self
|
74
|
+
(friend_ids + inverse_friend_ids).include?(user.id)
|
75
|
+
end
|
76
|
+
|
77
|
+
# checks if a current user is connected to given user
|
78
|
+
def connected_with?(user)
|
79
|
+
friendshiped_with?(user)
|
80
|
+
end
|
81
|
+
|
82
|
+
# checks if a current user received invitation from given user
|
83
|
+
def invited_by?(user)
|
84
|
+
user.friend_ids.include?(self.id) or user.pending_friend_ids.include?(self.id)
|
85
|
+
end
|
86
|
+
|
87
|
+
# checks if a current user invited given user
|
88
|
+
def invited?(user)
|
89
|
+
self.friend_ids.include?(user.id) or self.pending_friend_ids.include?(user.id)
|
90
|
+
end
|
91
|
+
|
92
|
+
# deletes a friendship
|
93
|
+
def remove_friendship(user)
|
94
|
+
friend_ids.delete(user.id)
|
95
|
+
user.inverse_friend_ids.delete(self.id)
|
96
|
+
inverse_friend_ids.delete(user.id)
|
97
|
+
user.friend_ids.delete(self.id)
|
98
|
+
pending_friend_ids.delete(user.id)
|
99
|
+
user.pending_inverse_friend_ids.delete(self.id)
|
100
|
+
pending_inverse_friend_ids.delete(user.id)
|
101
|
+
user.pending_friend_ids.delete(self.id)
|
102
|
+
self.save && user.save
|
103
|
+
end
|
104
|
+
|
105
|
+
# blocks a friendship
|
106
|
+
def block(user)
|
107
|
+
if inverse_friend_ids.include?(user.id)
|
108
|
+
inverse_friend_ids.delete(user.id)
|
109
|
+
user.friend_ids.delete(self.id)
|
110
|
+
blocked_inverse_friend_ids << user.id
|
111
|
+
elsif pending_inverse_friend_ids.include?(user.id)
|
112
|
+
pending_inverse_friend_ids.delete(user.id)
|
113
|
+
user.pending_friend_ids.delete(self.id)
|
114
|
+
blocked_pending_inverse_friend_ids << user.id
|
115
|
+
elsif friend_ids.include?(user.id)
|
116
|
+
friend_ids.delete(user.id)
|
117
|
+
user.inverse_friend_ids.delete(user.id)
|
118
|
+
blocked_friend_ids << user.id
|
119
|
+
else
|
120
|
+
return false
|
121
|
+
end
|
122
|
+
|
123
|
+
self.save
|
124
|
+
end
|
125
|
+
|
126
|
+
# unblocks a friendship
|
127
|
+
def unblock(user)
|
128
|
+
if blocked_inverse_friend_ids.include?(user.id)
|
129
|
+
blocked_inverse_friend_ids.delete(user.id)
|
130
|
+
user.blocked_friend_ids.delete(self.id)
|
131
|
+
inverse_friend_ids << user.id
|
132
|
+
user.friend_ids << self.id
|
133
|
+
elsif blocked_pending_inverse_friend_ids.include?(user.id)
|
134
|
+
blocked_pending_inverse_friend_ids.delete(user.id)
|
135
|
+
pending_inverse_friend_ids << user.id
|
136
|
+
user.pending_friend_ids << self.id
|
137
|
+
elsif blocked_friend_ids.include?(user.id)
|
138
|
+
blocked_friend_ids.delete(user.id)
|
139
|
+
user.blocked_inverse_friend_ids.delete(self.id)
|
140
|
+
friend_ids << user.id
|
141
|
+
user.inverse_friend_ids << self.id
|
142
|
+
else
|
143
|
+
return false
|
144
|
+
end
|
145
|
+
|
146
|
+
self.save && user.save
|
147
|
+
end
|
148
|
+
|
149
|
+
# returns the list of blocked friends
|
150
|
+
def blocked
|
151
|
+
blocked_ids = blocked_friend_ids + blocked_inverse_friend_ids + blocked_pending_inverse_friend_ids
|
152
|
+
self.class.find(blocked_ids)
|
153
|
+
end
|
154
|
+
|
155
|
+
# checks if a user is blocked
|
156
|
+
def blocked?(user)
|
157
|
+
(blocked_friend_ids + blocked_inverse_friend_ids + blocked_pending_inverse_friend_ids).include?(user.id) or user.blocked_pending_inverse_friend_ids.include?(self.id)
|
158
|
+
end
|
159
|
+
|
160
|
+
# check if any friendship exists with another user
|
161
|
+
def friendshiped_with?(user)
|
162
|
+
(friend_ids + inverse_friend_ids + pending_friend_ids + pending_inverse_friend_ids + blocked_friend_ids).include?(user.id)
|
163
|
+
end
|
164
|
+
|
165
|
+
# deletes all the friendships
|
166
|
+
def delete_all_friendships
|
167
|
+
friend_ids.clear
|
168
|
+
inverse_friend_ids.clear
|
169
|
+
pending_friend_ids.clear
|
170
|
+
pending_inverse_friend_ids.clear
|
171
|
+
blocked_friend_ids.clear
|
172
|
+
blocked_inverse_friend_ids.clear
|
173
|
+
blocked_pending_friend_ids.clear
|
174
|
+
blocked_pending_inverse_friend_ids.clear
|
175
|
+
self.save
|
176
|
+
end
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/lib/amistad/version.rb
CHANGED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
ActiveRecord::Base.establish_connection(
|
5
|
+
:adapter => "sqlite3",
|
6
|
+
:database => ":memory:"
|
7
|
+
)
|
8
|
+
|
9
|
+
ActiveRecord::Migration.verbose = false
|
10
|
+
|
11
|
+
ActiveRecord::Schema.define do
|
12
|
+
create_table :users, :force => true do |t|
|
13
|
+
t.string :name, :null => false
|
14
|
+
end
|
15
|
+
|
16
|
+
create_table :friendships, :force => true do |t|
|
17
|
+
t.integer :user_id
|
18
|
+
t.integer :friend_id
|
19
|
+
t.integer :blocker_id
|
20
|
+
t.boolean :pending, :default => true
|
21
|
+
end
|
22
|
+
|
23
|
+
add_index :friendships, [:user_id, :friend_id], :unique => true
|
24
|
+
end
|
25
|
+
|
26
|
+
class User < ActiveRecord::Base
|
27
|
+
include Amistad::FriendModel
|
28
|
+
end
|
29
|
+
|
30
|
+
class Friendship < ActiveRecord::Base
|
31
|
+
include Amistad::FriendshipModel
|
32
|
+
end
|
33
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'mongoid_spec_helper'
|
2
|
+
|
3
|
+
describe Amistad::Mongoid::FriendModel do
|
4
|
+
def reset_friendships
|
5
|
+
%w(john jane david james peter mary victoria elisabeth).each do |var|
|
6
|
+
eval "@#{var}.delete_all_friendships.should be_true"
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
before(:all) do
|
11
|
+
Object.send(:remove_const, :User) if Object.const_defined?(:User)
|
12
|
+
User = Class.new
|
13
|
+
User.class_exec do
|
14
|
+
include Mongoid::Document
|
15
|
+
include Amistad::FriendModel
|
16
|
+
field :name, :required => true
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
it_should_behave_like "a friend model"
|
21
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require 'mongoid'
|
3
|
+
|
4
|
+
Mongoid.configure do |config|
|
5
|
+
name = "amistad_test"
|
6
|
+
host = "localhost"
|
7
|
+
config.master = Mongo::Connection.new.db(name)
|
8
|
+
config.slaves = [
|
9
|
+
Mongo::Connection.new(host, 27017, :slave_ok => true).db(name)
|
10
|
+
]
|
11
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,33 +1,3 @@
|
|
1
1
|
require 'rspec'
|
2
|
-
require 'active_record'
|
3
2
|
require 'amistad'
|
4
|
-
|
5
|
-
ActiveRecord::Base.establish_connection(
|
6
|
-
:adapter => "sqlite3",
|
7
|
-
:database => ":memory:"
|
8
|
-
)
|
9
|
-
|
10
|
-
ActiveRecord::Migration.verbose = false
|
11
|
-
|
12
|
-
ActiveRecord::Schema.define do
|
13
|
-
create_table :users, :force => true do |t|
|
14
|
-
t.string :name, :null => false
|
15
|
-
end
|
16
|
-
|
17
|
-
create_table :friendships, :force => true do |t|
|
18
|
-
t.integer :user_id
|
19
|
-
t.integer :friend_id
|
20
|
-
t.integer :blocker_id
|
21
|
-
t.boolean :pending, :default => true
|
22
|
-
end
|
23
|
-
|
24
|
-
add_index :friendships, [:user_id, :friend_id], :unique => true
|
25
|
-
end
|
26
|
-
|
27
|
-
class User < ActiveRecord::Base
|
28
|
-
include Amistad::FriendModel
|
29
|
-
end
|
30
|
-
|
31
|
-
class Friendship < ActiveRecord::Base
|
32
|
-
include Amistad::FriendshipModel
|
33
|
-
end
|
3
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
@@ -1,7 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
describe Amistad::FriendModel do
|
4
|
-
|
1
|
+
shared_examples_for "a friend model" do
|
5
2
|
before(:all) do
|
6
3
|
%w(John Jane David James Peter Mary Victoria Elisabeth).each do |name|
|
7
4
|
instance_variable_set("@#{name.downcase}".to_sym, User.create(:name => name))
|
@@ -9,8 +6,8 @@ describe Amistad::FriendModel do
|
|
9
6
|
end
|
10
7
|
|
11
8
|
context "when creating friendships" do
|
12
|
-
before do
|
13
|
-
|
9
|
+
before(:each) do
|
10
|
+
reset_friendships
|
14
11
|
end
|
15
12
|
|
16
13
|
it "should invite other users to friends" do
|
@@ -62,8 +59,8 @@ describe Amistad::FriendModel do
|
|
62
59
|
end
|
63
60
|
|
64
61
|
context "when listing friendships" do
|
65
|
-
before do
|
66
|
-
|
62
|
+
before(:each) do
|
63
|
+
reset_friendships
|
67
64
|
@john.invite(@jane).should be_true
|
68
65
|
@peter.invite(@john).should be_true
|
69
66
|
@john.invite(@james).should be_true
|
@@ -77,6 +74,7 @@ describe Amistad::FriendModel do
|
|
77
74
|
end
|
78
75
|
|
79
76
|
it "should not list non-friended users" do
|
77
|
+
@victoria.friends.should be_empty
|
80
78
|
@john.friends.should =~ [@mary, @james]
|
81
79
|
@john.friends.should_not include(@peter)
|
82
80
|
@john.friends.should_not include(@victoria)
|
@@ -159,8 +157,8 @@ describe Amistad::FriendModel do
|
|
159
157
|
end
|
160
158
|
|
161
159
|
context "when removing friendships" do
|
162
|
-
before do
|
163
|
-
|
160
|
+
before(:each) do
|
161
|
+
reset_friendships
|
164
162
|
@jane.invite(@james).should be_true
|
165
163
|
@james.approve(@jane).should be_true
|
166
164
|
@james.invite(@victoria).should be_true
|
@@ -180,7 +178,7 @@ describe Amistad::FriendModel do
|
|
180
178
|
@mary.friends.size.should == 1
|
181
179
|
@mary.friends.should include(@victoria)
|
182
180
|
@mary.invited_by.should include(@victoria)
|
183
|
-
@victoria.
|
181
|
+
@victoria.remove_friendship(@mary).should be_true
|
184
182
|
@victoria.friends.size.should == 2
|
185
183
|
@victoria.friends.should_not include(@mary)
|
186
184
|
@victoria.invited.should_not include(@mary)
|
@@ -196,7 +194,7 @@ describe Amistad::FriendModel do
|
|
196
194
|
@james.friends.size.should == 2
|
197
195
|
@james.friends.should include(@victoria)
|
198
196
|
@james.invited.should include(@victoria)
|
199
|
-
@victoria.
|
197
|
+
@victoria.remove_friendship(@james).should be_true
|
200
198
|
@victoria.friends.size.should == 2
|
201
199
|
@victoria.friends.should_not include(@james)
|
202
200
|
@victoria.invited_by.should_not include(@james)
|
@@ -210,7 +208,7 @@ describe Amistad::FriendModel do
|
|
210
208
|
@victoria.pending_invited.should include(@elisabeth)
|
211
209
|
@elisabeth.pending_invited_by.size.should == 1
|
212
210
|
@elisabeth.pending_invited_by.should include(@victoria)
|
213
|
-
@victoria.
|
211
|
+
@victoria.remove_friendship(@elisabeth).should be_true
|
214
212
|
[@victoria, @elisabeth].map(&:reload)
|
215
213
|
@victoria.pending_invited.size.should == 0
|
216
214
|
@victoria.pending_invited.should_not include(@elisabeth)
|
@@ -223,7 +221,7 @@ describe Amistad::FriendModel do
|
|
223
221
|
@victoria.pending_invited_by.should include(@peter)
|
224
222
|
@peter.pending_invited.count.should == 1
|
225
223
|
@peter.pending_invited.should include(@victoria)
|
226
|
-
@victoria.
|
224
|
+
@victoria.remove_friendship(@peter).should be_true
|
227
225
|
[@victoria, @peter].map(&:reload)
|
228
226
|
@victoria.pending_invited_by.count.should == 0
|
229
227
|
@victoria.pending_invited_by.should_not include(@peter)
|
@@ -233,8 +231,8 @@ describe Amistad::FriendModel do
|
|
233
231
|
end
|
234
232
|
|
235
233
|
context "when blocking friendships" do
|
236
|
-
before do
|
237
|
-
|
234
|
+
before(:each) do
|
235
|
+
reset_friendships
|
238
236
|
@john.invite(@james).should be_true
|
239
237
|
@james.approve(@john).should be_true
|
240
238
|
@james.block(@john).should be_true
|
@@ -295,7 +293,7 @@ describe Amistad::FriendModel do
|
|
295
293
|
@james.blocked.each do |user|
|
296
294
|
@james.friends.should_not include(user)
|
297
295
|
user.friends.should_not include(@james)
|
298
|
-
|
296
|
+
end
|
299
297
|
end
|
300
298
|
|
301
299
|
it "should not list blocked users in invited" do
|
@@ -323,8 +321,8 @@ describe Amistad::FriendModel do
|
|
323
321
|
end
|
324
322
|
|
325
323
|
context "when unblocking friendships" do
|
326
|
-
before do
|
327
|
-
|
324
|
+
before(:each) do
|
325
|
+
reset_friendships
|
328
326
|
@john.invite(@james).should be_true
|
329
327
|
@james.approve(@john).should be_true
|
330
328
|
@john.block(@james).should be_true
|
@@ -391,4 +389,4 @@ describe Amistad::FriendModel do
|
|
391
389
|
@david.pending_invited_by.should == [@victoria]
|
392
390
|
end
|
393
391
|
end
|
394
|
-
end
|
392
|
+
end
|
metadata
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: amistad
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 6
|
8
|
-
- 0
|
9
|
-
version: 0.6.0
|
4
|
+
prerelease:
|
5
|
+
version: 0.7.0
|
10
6
|
platform: ruby
|
11
7
|
authors:
|
12
8
|
- Rawane ZOSSOU
|
@@ -14,7 +10,7 @@ autorequire:
|
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
12
|
|
17
|
-
date: 2011-
|
13
|
+
date: 2011-02-12 00:00:00 +01:00
|
18
14
|
default_executable:
|
19
15
|
dependencies:
|
20
16
|
- !ruby/object:Gem::Dependency
|
@@ -25,10 +21,6 @@ dependencies:
|
|
25
21
|
requirements:
|
26
22
|
- - ~>
|
27
23
|
- !ruby/object:Gem::Version
|
28
|
-
segments:
|
29
|
-
- 1
|
30
|
-
- 0
|
31
|
-
- 7
|
32
24
|
version: 1.0.7
|
33
25
|
type: :development
|
34
26
|
version_requirements: *id001
|
@@ -40,11 +32,7 @@ dependencies:
|
|
40
32
|
requirements:
|
41
33
|
- - ~>
|
42
34
|
- !ruby/object:Gem::Version
|
43
|
-
|
44
|
-
- 2
|
45
|
-
- 4
|
46
|
-
- 0
|
47
|
-
version: 2.4.0
|
35
|
+
version: 2.5.0
|
48
36
|
type: :development
|
49
37
|
version_requirements: *id002
|
50
38
|
- !ruby/object:Gem::Dependency
|
@@ -55,11 +43,7 @@ dependencies:
|
|
55
43
|
requirements:
|
56
44
|
- - ~>
|
57
45
|
- !ruby/object:Gem::Version
|
58
|
-
|
59
|
-
- 3
|
60
|
-
- 0
|
61
|
-
- 3
|
62
|
-
version: 3.0.3
|
46
|
+
version: 3.0.4
|
63
47
|
type: :development
|
64
48
|
version_requirements: *id003
|
65
49
|
- !ruby/object:Gem::Dependency
|
@@ -70,13 +54,31 @@ dependencies:
|
|
70
54
|
requirements:
|
71
55
|
- - "="
|
72
56
|
- !ruby/object:Gem::Version
|
73
|
-
segments:
|
74
|
-
- 1
|
75
|
-
- 3
|
76
|
-
- 2
|
77
57
|
version: 1.3.2
|
78
58
|
type: :development
|
79
59
|
version_requirements: *id004
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: mongoid
|
62
|
+
prerelease: false
|
63
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
64
|
+
none: false
|
65
|
+
requirements:
|
66
|
+
- - ~>
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: 2.0.0.rc.7
|
69
|
+
type: :development
|
70
|
+
version_requirements: *id005
|
71
|
+
- !ruby/object:Gem::Dependency
|
72
|
+
name: bson_ext
|
73
|
+
prerelease: false
|
74
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
75
|
+
none: false
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "1.2"
|
80
|
+
type: :development
|
81
|
+
version_requirements: *id006
|
80
82
|
description: Extends your user model with friendships management methods
|
81
83
|
email:
|
82
84
|
- dev@raw1z.fr
|
@@ -95,15 +97,22 @@ files:
|
|
95
97
|
- Rakefile
|
96
98
|
- amistad.gemspec
|
97
99
|
- lib/amistad.rb
|
100
|
+
- lib/amistad/active_record/friend_model.rb
|
101
|
+
- lib/amistad/active_record/friendship_model.rb
|
98
102
|
- lib/amistad/friend_model.rb
|
99
103
|
- lib/amistad/friendship_model.rb
|
104
|
+
- lib/amistad/mongoid/friend_model.rb
|
100
105
|
- lib/amistad/version.rb
|
101
106
|
- lib/generators/amistad/install/install_generator.rb
|
102
107
|
- lib/generators/amistad/install/templates/create_friendships.rb
|
103
108
|
- lib/generators/amistad/install/templates/friendship.rb
|
104
|
-
- spec/
|
105
|
-
- spec/
|
109
|
+
- spec/activerecord_friend_model_spec.rb
|
110
|
+
- spec/activerecord_friendship_model_spec.rb
|
111
|
+
- spec/activerecord_spec_helper.rb
|
112
|
+
- spec/mongoid_friend_model_spec.rb
|
113
|
+
- spec/mongoid_spec_helper.rb
|
106
114
|
- spec/spec_helper.rb
|
115
|
+
- spec/support/friend_examples.rb
|
107
116
|
has_rdoc: true
|
108
117
|
homepage: http://github.com/raw1z/amistad
|
109
118
|
licenses: []
|
@@ -118,25 +127,25 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
127
|
requirements:
|
119
128
|
- - ">="
|
120
129
|
- !ruby/object:Gem::Version
|
121
|
-
segments:
|
122
|
-
- 0
|
123
130
|
version: "0"
|
124
131
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
125
132
|
none: false
|
126
133
|
requirements:
|
127
134
|
- - ">="
|
128
135
|
- !ruby/object:Gem::Version
|
129
|
-
segments:
|
130
|
-
- 0
|
131
136
|
version: "0"
|
132
137
|
requirements: []
|
133
138
|
|
134
139
|
rubyforge_project: amistad
|
135
|
-
rubygems_version: 1.
|
140
|
+
rubygems_version: 1.5.0
|
136
141
|
signing_key:
|
137
142
|
specification_version: 3
|
138
143
|
summary: Adds friendships management into a rails 3.0 application
|
139
144
|
test_files:
|
140
|
-
- spec/
|
141
|
-
- spec/
|
145
|
+
- spec/activerecord_friend_model_spec.rb
|
146
|
+
- spec/activerecord_friendship_model_spec.rb
|
147
|
+
- spec/activerecord_spec_helper.rb
|
148
|
+
- spec/mongoid_friend_model_spec.rb
|
149
|
+
- spec/mongoid_spec_helper.rb
|
142
150
|
- spec/spec_helper.rb
|
151
|
+
- spec/support/friend_examples.rb
|