2012-03-02 79 views
1

我有一个Array的数组,如果用户的Facebook好友列表如下:过滤基于数据库记录

[ 
    { 'name' => 'John Mallock', 'id' => '123123' }, 
    { 'name' => 'Susan Freely', 'id' => '123123123' }, 
    ... 
] 

我想过滤此列表中存在的users表在我的Rails应用程序条目。目前,我正在做这个如下:

graph = Koala::Facebook::API.new 'access_token' 
friends = graph.get_connections 'me', 'friends' # Returns the structure above 
friends.select! { |f| User.exists? :facebook_id => f['id'] } 

这导致SELECT查询列表中的每一位朋友,这是明显的低效。

是否有一种更有效的方法来过滤基于数据库记录的列表?

+0

建立一个所有ID的数组,并一次检查它们。然后,您将拥有一组用户以及现有ID的数组。从这一点,你只是过滤。 (作为评论发布,因为我不知道Ruby或FB API,所以我希望我没有忽略任何东西。) – Corbin 2012-03-02 19:51:29

回答

2

可能做到这一点的最简单的方式是一个数组传递到在一个红宝石方法where。如果你在一个阵列通过,它将被转换成IN查询数据库:

users = User.where(:facebook_id => friends.map{|f| f['id']}) 

# generates: SELECT * FROM users where users.facebook_id IN (f1, f2, etc..) 

如果您需要知道哪些条目在friends对应的用户,然后你可以调用一个选择上的朋友:

existing_facebook_ids = users.map(&:facebook_id) 
friends.select! {|f| existing_facebook_ids.include?(f['id'])} 

请注意,如果您在两个阵列中都有相当数量的记录,则上述效率相当低。您可能想要稍微优化一下,或者更好的是,不要使用friends数组,而只是在包含相同数据的用户记录上进行迭代。

+0

我同意它效率低下,但它会暂时工作。谢谢您的帮助。这使我的查询从1 /朋友减少到1。 :) – 2012-03-02 20:29:04

0

您可以使用SQL IN查询一次选择所有ID。

friend_ids = friends.map{|f| f['id']} 
User.scoped(:conditions => ['id IN (?)', friend_ids])