module ActiveRecord class Base def is_actor? false end alias :is_actor :is_actor? end end module SharpSocial module Mixins module Actor extend ActiveSupport::Concern included do #after_destroy { SharpSocial.follow_model.remove_followables(self) } def is_actor? true end alias :is_actor :is_actor? def follow(actor) raise ArgumentError, "#{followable} is not an actor!" unless actor.respond_to?(:is_actor?) Follow.where(actor_id: actor.id, actor_type: actor.class.name, follower_id: self.id, follower_type: self.class.name).first_or_create end alias :follow! :follow def unfollow(actor) raise ArgumentError, "#{followable} is not artor!" unless actor.respond_to?(:is_actor?) if follow = Follow.where(actor_id: actor.id, actor_type: actor.class.name, follower_id: self.id, follower_type: self.class.name).first follow.destroy end end alias :unfollow! :unfollow def is_followed(follower) Follow.where(actor_id: self.id, actor_type: self.class.name, follower_id: follower.id, follower_type: follower.class.name).first end alias :is_followed? :is_followed def is_following(actor) raise ArgumentError, "#{followable} is not artor!" unless actor.respond_to?(:is_actor?) actor.is_followed? self end alias :is_following? :is_following def is_friend(actor) actor.is_followed(self) and self.is_followed(actor) end alias :is_friend? :is_friend def followers(type=nil) type = type || self.class.name Follow.where(actor_id: self.id, actor_type: self.class.name, follower_type: type) end def followings(type=nil) type ||= self.class.name Follow.where(follower_id: self.id, follower_type: self.class.name, actor_type: type) end def followers_count(type=nil) followers(type).count end def followings_count(type=nil) followings(type).count end end end end end