如何将Users表加入100个排名记录列表以避免100多个额外的用户查询?

时间:2017-06-28 02:54:45

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

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

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)?理想情况下使用较少的数据库查询。

由于

1 个答案:

答案 0 :(得分:4)

您想使用active record :joins method。假设#include <iostream> double AvgFunction(int numTemp, int* temp); int main() { int numTemp; std::cout << "Please input the number of temperatures to be read" << std::endl; std::cin >> numTemp; int temp[numTemp]; for (int i = 0;i < numTemp; i++) { std::cout << "Please input temperatures for day "<< (i+1) << std::endl; std::cin >> temp[i]; } std::cout << AvgFunction(numTemp, temp) << std::endl; return 0; } double AvgFunction(int numTemp, int* temp) { double returnVal = 0; for(int i = 0; i < numTemp; i++) { returnVal += temp[i]; } returnVal /= numTemp; return returnVal; } 表还有一个名为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) 在一个查询中加载每个RankingUser关联的includes(@thanh在评论中提到,他也链接了值得检查的文档) 。然后,您可以遍历评级并获取displayNamephoto_url,而无需进行额外的数据库调用。

编辑2:) 根据{{​​3}}我的第一个答案应该有效,但是由于:select返回一个ActiveRecord :: Relation对象,它只包含你调用:select的类的对象(在我们的例子中{{}} 1}})。这些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')`