module Recommendable::Rater::Recommender

Public Instance Methods

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