2011-04-05 64 views
1

我正在为我的项目中的用户构建推荐方法。用户在查看,创建,评论或与对象交互时(根据操作加权)生成兴趣记录。查找条件需要重构/优化多态关联

我已经写了一个查找用户兴趣的查找方法,然后找到对这些项目也感兴趣的用户。但是,它的效率非常低,可以根据用户的兴趣(最多50个)进行多次db调用。

这里是发生了什么事情的砍下版本:

#User.rb 
... 
has_many :interests, :as => :interestable, :dependent => :destroy 

def recommendations 
    recommendations = [] 

    Interest.for(self).limit(50).each do |item| 
    recommendations << Interest.other_fans_of(item) 
    end 

    user_ids = recommendations.flatten.map(&:user_id).uniq 
end 
... 

#interest.rb 

... 

belongs_to :user 
belongs_to :interestable, :polymorphic => true 

named_scope :for, lambda { |user| { :conditions => { :user_id => user.id } } } 
named_scope :limit, lambda { |num| { :limit => num } } 
named_scope :other_fans_of, lambda { |interest| { :conditions => { :interestable_type => interest.interestable_type, :interestable_id => interest.interestable_id } } } 
default_scope :order => "weight DESC" 

... 

是否有任何SQL神医那里谁可以把它转换成一个漂亮干净的DB调用?

回答

0

像这样的东西应该做的工作。有可能有更漂亮的方式...

class User < ActiveRecord::Base 
    #... 
    def recommendations 
    # get a list of the relevant interests 
    the_interests = Interest.for(self).limit(50).map{|x| [x.interestable_type, x.interestable_id]} 
    # make some sql 
    conditions = the_interests.map{|x| "(`interestable_type`=? AND `interestable_id`=?)"}.join(" OR ") 
    # use ruby magic to make a valid finder and get the other user_ids 
    user_ids = Interest.all(:select => '`user_id`', :conditions => [conditions, *(the_interests.flatten)]).map(&:user_id).uniq 
    end 
    #... 
end