user107680
user107680

Reputation: 81

Finding similar values in a hash/array in Ruby

I am trying to compute how many 'tips' a 'user' has in common with another user. Here is my method doing so:

class User < ActiveRecord::Base
  has_many :tips, :inverse_of => :user
  ...
  public
  def tip_affinity_with(user)
    tipAffinity = 0

    user.tips.each do |tip|
      if self.tips.include?(tip)
        tipAffinity = tipAffinity + 1
      end
    end

    return tipAffinity
  end
end

I know that some users have tips that they have both rated, but in my table, the tipAffinity is 0 for all of the users.

What could be the problem? Any help is greatly appreciated!


EDIT: Here is the join model, Affinity:

class Affinity < ActiveRecord::Base
  attr_accessible :user_A_id, :user_B_id, :tips_value, :tips_valid, :profile_value, :profile_valid, :value

  belongs_to :users
  belongs_to :inverse_user, :class_name => "Users"

  validates :tips_value, presence: true
  validates :profile_value, presence: true
  validates :user_A_id, presence: true
  validates :user_B_id, presence: true

  before_update :set_value
  before_create :set_value

  private
  def set_value
    self.value = 0.7*self.tips_value + 0.3*self.profile_value
    #self.value = PredictionConfigs.find(1)*self.tips_value + (1 - PredictionConfigs.find(1))*self.profile_value #Use prediction configs
  end
end

I am indeed trying to find the intersection of two hashes. The two hashes are the tips of two users, one is self, the other is user.

Thanks again!

Upvotes: 0

Views: 45

Answers (2)

Cade
Cade

Reputation: 3181

If your models are set up correctly, this can be done in the database with:

def tip_affinity_with(user)
  user.tips.where(id: tip_ids).count
end

It seems to me based on the comments (and your example code) that your models may not be set up correctly. Do you have a join model between users and tips? Something like:

class User < ActiveRecord::Base
  has_many :suggestions
  has_many :tips, through: :suggestions
end

class Suggestion < ActiveRecord::Base
  belongs_to :user
  belongs_to :tip
end

class Tip < ActiveRecord::Base
  has_many :suggestions
  has_many :users, through: :suggestions
end

It'd help to see your Tip model. My guess is that Tip belongs_to :user and that's why you aren't getting any overlap between users, but I could be wrong.

Here's some more reading from the Rails guides on has_many :through associations.

Upvotes: 0

tadman
tadman

Reputation: 211570

Although this is brutally inefficient, you might try:

(user.tips & self.tips).length

You really want to avoid loading models if you're not using the data contained within them. This should be possible to compute using only what's present in the database. Something like:

(user.tip_ids & self.tip_ids).length

Upvotes: 1

Related Questions