Skip to content

Instantly share code, notes, and snippets.

@seivan
Created December 21, 2010 21:00
Show Gist options
  • Save seivan/750598 to your computer and use it in GitHub Desktop.
Save seivan/750598 to your computer and use it in GitHub Desktop.
User class
class User < ActiveRecord::Base
def following_ids
FriendShip.following_ids_for(self)
end
def followings
User.where(:id => following_ids)
end
def following?(user)
FriendShip.following?(self, user)
end
def follow!(user)
FriendShip.follow!(self, user)
end
def friend_ids
FriendShip.friend_ids_for(self)
end
def friends
User.where(:id => friend_ids)
end
def follower_ids
FriendShip.follower_ids_for(self)
end
def followers
User.where(:id => follower_ids)
end
end
class FriendShip
#The datastructure we are working on are SETS, the are unordered lists with unique elements. Perfect for friendships
#Every "method" in redis is prefixed with the datastructures first letter. SET => s, ergo sMembers. Members in the sets.
def self.following_ids_for(user)
Red.smembers("user:#{user.id}:followings")
end
def self.follower_ids_for(user)
Red.smembers("user:#{user.id}:followers")
end
def self.follow!(user, followed_user)
return false if user == followed_user
Red.sadd("user:#{user.id}:followings", followed_user.id)
Red.sadd("user:#{followed_user.id}:followers", user.id)
true
end
def self.following?(user, other_user)
Red.sismember("user:#{user.id}:followings", other_user.id)
#Checks if other_user is a user under current_users followings
end
def self.friend_ids_for(user)
Red.sinter("user:#{user.id}:followings", "user:#{user.id}:followers")
#Intersects the two SETS
# http://www.redis.io/commands/sinter
end
end
The conventions with Redis are that you use colon as a separator.
user:user_id:followings
The first part can be the model, the table, the second is the pk, the id, an identifier so we can differentiate it, the third part is the attribute, the column, the variable we want out.
So we have stuff like
user:#{user_id}:followings
or
user:#{user_id}:followers
That is a convention, not a strict requirement.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment