【问题标题】:rails where() sql query on arrayrails where() sql查询数组
【发布时间】:2011-08-01 14:56:58
【问题描述】:

我会尽可能地解释这一点。我有一个关于用户帖子的查询:

@selected_posts = Posts.where(:category => "Baseball")

我想写以下声明。这是伪术语:

User.where(user has a post in @selected_posts)

请记住,我有一个多对多关系设置,所以 post.user 是可用的。

有什么想法吗?

/编辑

@posts_matches = User.includes(@selected_posts).map{ |user|

      [user.company_name, user.posts.count, user.username]

    }.sort

基本上,我需要上述工作,以便它使用在 selected_posts 中有帖子的用户,而不是我们数据库中的每个用户。

【问题讨论】:

  • 虽然 Kandada 的回答是使用手工 SQL 解决问题的好方法,但有时需要使用 ruby​​(例如,如果您想使用在步骤中检索到的信息来做事)构建查询的方式)。请在下面查看我的答案,以获取使用更多 ruby​​ 和更少 sql 检索您正在寻找的信息的方法。
  • 我同意,我按照你的方式去了。

标签: ruby-on-rails ruby ruby-on-rails-3


【解决方案1】:

试试这个:

user.posts.where("posts.category = ?", "Baseball")

编辑 1:

user.posts.where("posts.id IN (?)", @selected_posts)

编辑 2:

User.select("users.company_name, count(posts.id) userpost_count, user.username").
  joins(:posts).
  where("posts.id IN (?)", @selected_posts).
  order("users.company_name, userpost_count, user.username")

【讨论】:

  • 嗯,这是一个动态页面,所以我需要使用@selected_posts 变量,因为类别会经常变化。有什么想法吗?感谢您的帮助
  • 谢谢 - 这很接近,但我需要生成一个用户数组,这些用户在该查询中发布了帖子(请参阅编辑)不知道我将如何用我所拥有的实现你的代码
  • 更新答案看看。
  • 我已更新答案以修复语法错误。看看吧。
【解决方案2】:

只需使用以下内容:

User.find(@selected_posts.map(&:user_id).uniq)

这会从所有选定的帖子中获取用户 ID,将它们转换为数组,并删除所有重复项。将数组传递给用户只会找到所有具有匹配 id 的用户。问题解决了。

要将其与您在问题中显示的内容结合起来,您可以这样写:

@posts_matches = User.find(@selected_posts.map(&:user_id).uniq).map{ |user|
  [user.company_name, user.posts.size, user.username]
}

使用size 代替count 来计算关系,因为Rails 缓存了size 方法并且自动不会多次查找它。这对性能更好。

不确定您在查询结束时尝试使用 Array#sort 完成什么,但您始终可以执行以下操作:

@users_with_posts_in_selected = User.find(@selected_posts.map(&:user_id).uniq).order('username DESC')

【讨论】:

  • 一般来说,我建议不要在这种情况下使用map,因为你强迫 ruby​​ 做数据库可以做的事情——数据库通常更快。当您调用map(&:user_id) 时,您正在将该对象具体化为一个活动记录对象。使用pluck(:user_id).uniq,activerecord 会生成一个数据库可以优化的很好的查询
【解决方案3】:

我不明白你的问题,但你可以像这样将数组传递给 where 方法:

where(:id => @selected_posts.map(&:id))

它会创建一个类似WHERE id IN (1,2,3,4)的SQL查询

【讨论】:

  • 很抱歉给您带来了困惑。基本上,@selected_posts 代表对Posts 的查询 - 例如,但不一定:@selected_posts = Posts.where(:category => "Baseball") 我只是想让我上面的@posts_matches 代码仅在具有@selected_posts 选择的帖子的用户上运行,而不是运行每个数据库中的单个用户。
  • 在 map 方法中缺少 & 符号 - 这会启动一个块并允许成功返回 ID 数组:where(:id => @selected_posts.map(&:id))
【解决方案4】:

根据您的关联,您选择的帖子已经拥有用户:

@selected_posts = Posts.where("posts.category =?", "Baseball")
@users = @selected_posts.collect(&:user);

您可能希望从 @users 中删除重复的用户。

【讨论】:

  • 谢谢。这很有帮助,但我不确定在我看来如何打印@users。因为现在我得到 -> 迈克,迈克,迈克,迈克......我怎么能得到迈克(4)呢?
  • 查看 stackoverflow.com/questions/569694/… 以计算数组中的重复项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-06-29
  • 1970-01-01
  • 2012-01-17
  • 1970-01-01
  • 1970-01-01
  • 2013-05-21
  • 1970-01-01
相关资源
最近更新 更多