Module: Recommendable::ActsAsRecommendedTo::RecommendationMethods

Defined in:
lib/recommendable/acts_as_recommended_to.rb

Instance Method Summary collapse

Instance Method Details

#disagreed_on_with(rater, options = {}) ⇒ Object



451
452
453
454
455
456
457
# File 'lib/recommendable/acts_as_recommended_to.rb', line 451

def disagreed_on_with rater, options = {}
  options.merge!({ :return_records => true })
  create_recommended_to_sets and rater.create_recommended_to_sets
  disagreements = disagreements_with rater, options
  destroy_recommended_to_sets and rater.destroy_recommended_to_sets
  return disagreements
end

#disliked_in_common_with(rater, options = {}) ⇒ Object



443
444
445
446
447
448
449
# File 'lib/recommendable/acts_as_recommended_to.rb', line 443

def disliked_in_common_with rater, options = {}
  options.merge!({ :return_records => true })
  create_recommended_to_sets and rater.create_recommended_to_sets
  disliked = common_dislikes_with rater, options
  destroy_recommended_to_sets and rater.destroy_recommended_to_sets
  return disliked
end

#liked_in_common_with(rater, options = {}) ⇒ Object



435
436
437
438
439
440
441
# File 'lib/recommendable/acts_as_recommended_to.rb', line 435

def liked_in_common_with rater, options = {}
  options.merge!({ :return_records => true })
  create_recommended_to_sets and rater.create_recommended_to_sets
  liked = common_likes_with rater, options
  destroy_recommended_to_sets and rater.destroy_recommended_to_sets
  return liked
end

#probability_of_disliking(object) ⇒ Float

Return the negation of the value calculated by #predict on self for a passed object.

Parameters:

  • object (Object)

    the object to fetch the probability for

Returns:

  • (Float)

    the likelihood of self disliking the passed object

See Also:

  • Recommendable::ActsAsRecommendedTo::RecommendationMethods.{{#probability_of_liking}


515
516
517
# File 'lib/recommendable/acts_as_recommended_to.rb', line 515

def probability_of_disliking object
  -probability_of_liking(object)
end

#probability_of_liking(object) ⇒ Float

Return the value calculated by #predict on self for a passed object.

Parameters:

  • object (Object)

    the object to fetch the probability for

Returns:

  • (Float)

    the likelihood of self liking the passed object



505
506
507
# File 'lib/recommendable/acts_as_recommended_to.rb', line 505

def probability_of_liking object
  Recommendable.redis.zscore predictions_set_for(object.class), object.redis_key
end

#rated?(object) ⇒ Boolean

Checks to see if self has already liked or disliked a passed object.

Parameters:

  • object (Object)

    the object you want to check

Returns:

  • (Boolean)

    true if self has liked or disliked object, false if not



404
405
406
# File 'lib/recommendable/acts_as_recommended_to.rb', line 404

def rated? object
  likes?(object) || dislikes?(object)
end

#rated_anything?Boolean

Checks to see if self has liked or disliked any objects yet.

Returns:

  • (Boolean)

    true if self has liked or disliked anything, false if not



411
412
413
# File 'lib/recommendable/acts_as_recommended_to.rb', line 411

def rated_anything?
  likes.count > 0 || dislikes.count > 0
end

#recommendations(count = 10) ⇒ Array

Get a list of recommendations for self. The whole point of this gem! Recommendations are returned in a descending order with the first index being the object that self has been found most likely to enjoy.

Parameters:

  • count (Fixnum) (defaults to: 10)

    the number of recmomendations to return

Returns:

  • (Array)

    an array of ActiveRecord objects that are recommendable



465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
# File 'lib/recommendable/acts_as_recommended_to.rb', line 465

def recommendations count = 10
  return [] if likes.count + dislikes.count == 0

  unioned_predictions = "#{self.class}:#{id}:predictions"
  Recommendable.redis.zunionstore unioned_predictions, Recommendable.recommendable_classes.map { |klass| predictions_set_for klass }
  
  recommendations = Recommendable.redis.zrevrange(unioned_predictions, 0, count - 1).map do |object|
    klass, id = object.split(":")
    klass.constantize.find(id)
  end
  
  recommendations = recommendations.first if count == 1

  Recommendable.redis.del(unioned_predictions) and return recommendations
end

Get a list of recommendations for self on a single recommendable type. Recommendations are returned in a descending order with the first index being the object that self has been found most likely to enjoy.

Parameters:

  • klass (Class, String, Symbol)

    the class to receive recommendations for. Can be the class constant, or a String/Symbol representation of the class name.

Returns:

  • (ActiveRecord::Relation)

    an ActiveRecord::Relation of recommendations



487
488
489
490
491
492
493
494
495
496
497
498
499
# File 'lib/recommendable/acts_as_recommended_to.rb', line 487

def recommended_for klass, count = 10
  return [] if likes_for(klass.base_class).count + dislikes_for(klass.base_class).count == 0 || Recommendable.redis.zcard(predictions_set_for(klass)) == 0
  ids = []

  (0...count).each do |i|
    prediction = Recommendable.redis.zrevrange(predictions_set_for(klass), i, i).first
    break unless prediction
    
    ids << prediction.split(":").last
  end

  return klass.to_s.classify.constantize.where('ID IN (?)', ids)
end

#similar_raters(options = {}) ⇒ Array

Get a list of raters that have been found to be the most similar to self. They are sorted in a descending fashion with the most similar rater in the first index.

Parameters:

  • options (Hash) (defaults to: {})

    the options for this query

Options Hash (options):

  • :count (Fixnum) — default: 10

    The number of raters to return

Returns:

  • (Array)

    An array of instances of your user class



422
423
424
425
426
427
428
429
430
431
432
433
# File 'lib/recommendable/acts_as_recommended_to.rb', line 422

def similar_raters options = {}
  defaults = { :count => 10 }
  options = defaults.merge options
  
  rater_ids = Recommendable.redis.zrevrange(similarity_set, 0, options[:count] - 1).map(&:to_i)
  raters = Recommendable.user_class.find rater_ids
  
  # The query loses the ordering, so...
  return raters.sort do |x, y|
    rater_ids.index(x.id) <=> rater_ids.index(y.id)
  end
end