【问题标题】:How to join the Users table to a list of 100 Ranking Records to avoid 100+ extra user queries?如何将用户表加入 100 条排名记录的列表以避免 100 多个额外的用户查询?
【发布时间】:2017-06-28 02:54:44
【问题描述】:

我有一个包含以下字段的排名模型:

Ranking.rb
  t.string "job_type"
  t.integer "user_id"
  t.integer "ranking"
  t.integer "total_ranked"
  t.integer "points"

此表由具有约 100 条记录的后台作业填充。然后我想让我的 API 查询并返回存储在排名中的记录结果,如下所示:

@rankings = Ranking.where(job_type: 'all_users').order('id ASC').select('id, user_id, ranking, points')

问题是我没有每个排名的相关用户信息。对于每个排名,我想使用 user_id 来查找用户并获取 User.displayName、User.photo_url。

如果我遍历@rankings 并对每条记录进行用户查询,这将是额外的 100 多个查询。

如何获取@rankings 并以某种方式包含相关的用户字段(User.displayName、User.photo_url)?理想情况下,数据库查询较少。

【问题讨论】:

标签: ruby-on-rails ruby postgresql ruby-on-rails-5


【解决方案1】:

您想使用active record :joins method。假设users 表还有一个名为id 而不是user_id 的字段,这应该可以工作:

Ranking
  .select('rankings.id, rankings.ranking, rankings.points, users.displayName, users.photo_url')
  .joins('JOIN users ON rankings.user_id = users.id')
  .where(job_type: 'all_users')
  .order('id ASC')`

编辑:我找不到从多个表中选择值的文档,只是堆叠旧的溢出答案。所以如果这不起作用,你可以这样做:

@rankings = Ranking.where(job_type: 'all_users').order('id ASC').select('id, user_id, ranking, points').includes(:user)

这将使用includes在一个查询中加载每个Ranking及其关联的User(@thanh在他的评论中提到,他也链接了值得一试的文档)。然后,您可以遍历评级并获得displayNamephoto_url,而无需进行额外的数据库调用。

编辑 2 :) 根据this answer,我的第一个答案应该有效,但是由于:select 返回一个ActiveRecord::Relation 对象,它只会包含您调用:select 的类的对象(在我们的例子中是Ranking)。 User 列将在这些 Ranking 对象上可用。看起来我们还需要为这些用户列设置别名,所以是这样的:

@rankings = Ranking
  .select('rankings.id, rankings.ranking, rankings.points, users.displayName as user_display_name, users.photo_url as user_photo_id')
  .joins('JOIN users ON rankings.user_id = users.id')
  .where(job_type: 'all_users')
  .order('id ASC')`

然后像这样访问它们:

@rankings.first.user_photo_url #=> "https://flikr.com/whatever"

【讨论】:

  • 第二个想法 @rankings = Ranking.where(job_type: 'all_users').order('id ASC').select('id, user_id, ranking, points').includes(:users) 错误 w Association named 'users' was not found on Ranking; perhaps you misspelled it?
  • @AnApprentice 是的,应该是 includes(:user)
猜你喜欢
  • 2019-09-09
  • 2016-03-27
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 1970-01-01
  • 2012-01-15
相关资源
最近更新 更多