Reputation: 81
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
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
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