测试对象是否存在于已连接的ActiveRecord查询中

时间:2014-02-12 00:35:32

标签: ruby-on-rails activerecord ruby-on-rails-4

我有与好友模型相关的用户模型(has_many / belongs_to)

加入后,我希望能够检查加入用户的朋友中是否存在某个朋友对象:

users = User.joins(:friends).where("some condition")    # subset of total friends
fs = Friend.all
fs.each do |f|
  if users.friends.includes?(f) # match!
     ...
  else   # no match
     ...
end

代码按原样不起作用,我在代码中获取此功能时遇到了困难。

1 个答案:

答案 0 :(得分:1)

尝试这样的事情:

users.friends.where(id: u.id).exists?

这应该生成如下查询:

SELECT 1 AS one FROM `users` WHERE `users`.`friend_id` = 42 AND `users`.`id` = 1 LIMIT 1

你要么取回1号(被认为是“真实的”),要么取回nil(被认为是“假的”)。

旁注:除非您以后需要使用u变量,否则您可以直接将some_id放在where子句中,而不是第二次User查询。

修改

刚刚注意到循环中的问题可能是导致原始问题的原因。当您加载用户列表时,除非您有一些limit子句或调用.first,否则您将获得一组用户。所以我猜你的应用程序在这一行上走了出来:

users.friends.includes?(f)

因为.friendsUser对象的方法,而不是数组。

所以你必须做一个嵌套循环,如下所示:

fs.each do |f|
    users.each do |u|
        u.friends.includes?(f)
    end
end

请注意,此方法可能会非常慢,具体取决于朋友和用户的数量。这是一个非常低效的算法,这就是我在评论中试图更好地理解你的情况的原因,因为我确信有更有效的方法来完成你的任务。