2011-03-21 44 views
0

我正尝试为用户构建一个Facebook样式的项目源。 Feed中会包含用户或用户关注的其他通知(例如“您关注的用户x开始阅读新书”)的用户所做的最新笔记(书籍)。你明白了。在rails中结合作用域活动记录查询

到目前为止,我有我的笔记类范围返回我想说明:

class Note < ActiveRecord::Base 
    scope :from_users_followed_by, lambda { |user| followed_by user } 

    def self.followed_by(user) 
    followed_ids = %(SELECT followed_id FROM relationships WHERE follower_id = :user_id) 
    where("user_id IN (#{followed_ids}) OR user_id = :user_id", { :user_id => user }) 
    end 
end 

,并在我的阅读类的类似范围返回内置记录时,用户开始读一本书:

class Reading < ActiveRecord::Base 
    scope :from_users_followed_by, lambda { |user| followed_by(user) } 

    def self.followed_by(user) 
    # is this not at risk of sql injection?? 
    followed_ids = %(SELECT followed_id FROM relationships WHERE follower_id = :user_id) 
    # return readings where user_id IN (an array of user_ids that the user follows) 
    where("reader_id IN (#{followed_ids}) OR reader_id = :user_id", { :user_id => user }) 
    end 
end 

现在,这工作正常,我可以从这些没有问题的对象的数组。我正努力将这两个查询合并到一个按创建时间正确排序的提要中。我当时可以做的最好的是我的用户类组合进料方法:

class User < ActiveRecord::Base 
    def combined_feed 
    feed = Note.from_users_followed_by(self) | Reading.from_users_followed_by(self) 

    feed.sort! do |a, b| 
     a.created_at <=> b.created_at 
    end 
    feed.reverse 
    end 
end 

它得到了我的组合进料,但给我的印象为窘况效率低下。我如何在rails中的数据库级别执行相同的操作?

回答

2

我想我可能会创建一个完全独立的模型,称为FeedItem。然后,当某些事件发生时(例如创建新笔记),您只需创建一个新的FeedItem记录。然后,您只有一个表格可以查询,并且它将以正确的顺序排列。