module Recommendable::Rater::Recommender
Public Instance Methods
recommended_for(klass, limit = 10, offset = 0)
click to toggle source
Fetch a list of recommendations for a passed class.
@param [String, Symbol, Class] klass the class from which to get recommendations @param [Fixnum] limit the number of recommendations to fetch (defaults to 10) @return [Array] a list of things this person's gonna love
# File lib/recommendable/rater/recommender.rb, line 24 def recommended_for(klass, limit = 10, offset = 0) recommended_set = Recommendable::Helpers::RedisKeyMapper.recommended_set_for(klass, self.id) return Recommendable.query(klass, []) unless rated_anything? && Recommendable.redis.zcard(recommended_set) > 0 ids = Recommendable.redis.zrevrange(recommended_set, 0, -1, :with_scores => true) ids = ids.select { |id, score| score > 0 }.map { |pair| pair.first } ids = sanitize_ids(ids, klass) order = ids.map { |id| "#{klass.quoted_table_name}.#{klass.quoted_primary_key} = ? DESC" }.join(', ') order = klass.send(:sanitize_sql_for_assignment, [order, *ids]) Recommendable.query(klass, ids).order(order).limit(limit).offset(offset) end
similar_raters(limit = 10, offset = 0)
click to toggle source
Get a list of raters that have been found to be the most similar to self. They are sorted by the calculated similarity value.
@param [Fixnum] limit the number of users to return (defaults to 10) @return [Array] An array of instances of your user class
# File lib/recommendable/rater/recommender.rb, line 9 def similar_raters(limit = 10, offset = 0) ids = Recommendable.redis.zrevrange(Recommendable::Helpers::RedisKeyMapper.similarity_set_for(id), 0, -1) ids = sanitize_ids(ids, self.class) order = ids.map { |id| "#{Recommendable.config.user_class.quoted_table_name}.#{Recommendable.config.user_class.quoted_primary_key} = ? DESC" }.join(', ') order = self.class.send(:sanitize_sql_for_assignment, [order, *ids]) Recommendable.query(self.class, ids).order(order).limit(limit).offset(offset) end
Private Instance Methods
remove_from_recommendable!()
click to toggle source
Removes a user from Recommendable
. Called internally on a before_destroy hook. @private
# File lib/recommendable/rater/recommender.rb, line 54 def remove_from_recommendable! sets = [] # SREM needed zsets = [] # ZREM needed keys = [] # DEL needed # Remove from other users' similarity ZSETs zsets += Recommendable.redis.keys(Recommendable::Helpers::RedisKeyMapper.similarity_set_for('*')) # Remove this user's similarity ZSET keys << Recommendable::Helpers::RedisKeyMapper.similarity_set_for(id) # For each ratable class... Recommendable.config.ratable_classes.each do |klass| # Remove this user from any class member's liked_by/disliked_by sets sets += Recommendable.redis.keys(Recommendable::Helpers::RedisKeyMapper.liked_by_set_for(klass, '*')) sets += Recommendable.redis.keys(Recommendable::Helpers::RedisKeyMapper.disliked_by_set_for(klass, '*')) # Remove this user's liked/disliked/hidden/bookmarked/recommended sets for the class keys << Recommendable::Helpers::RedisKeyMapper.liked_set_for(klass, id) keys << Recommendable::Helpers::RedisKeyMapper.disliked_set_for(klass, id) keys << Recommendable::Helpers::RedisKeyMapper.hidden_set_for(klass, id) keys << Recommendable::Helpers::RedisKeyMapper.bookmarked_set_for(klass, id) keys << Recommendable::Helpers::RedisKeyMapper.recommended_set_for(klass, id) end Recommendable.redis.pipelined do |redis| sets.each { |set| redis.srem(set, id) } zsets.each { |zset| redis.zrem(zset, id) } redis.del(*keys) end end
sanitize_ids(ids, klass)
click to toggle source
Sanitizes ids using klass type mapping @private
# File lib/recommendable/rater/recommender.rb, line 41 def sanitize_ids(ids, klass) ids.map{ |id| klass.new(klass.primary_key => id).send(klass.primary_key) }.compact end
unrecommend(obj)
click to toggle source
Removes an item from a user's set of recommendations @private
# File lib/recommendable/rater/recommender.rb, line 47 def unrecommend(obj) Recommendable.redis.zrem(Recommendable::Helpers::RedisKeyMapper.recommended_set_for(obj.class, id), obj.id) true end