Ruby on rails 将按联接表分页、包含和排序
所以,我在做一些类似的事情:Ruby on rails 将按联接表分页、包含和排序,ruby-on-rails,postgresql,activerecord,arel,Ruby On Rails,Postgresql,Activerecord,Arel,所以,我在做一些类似的事情: user.students.includes(:exams).ungraded.paginate(:page => params[:page]).order("exams.created_at desc") 然而,这导致了一个微妙的问题。在活动记录中的某些地方,该限制使其在学生id上产生了明显的影响,如下所示: SELECT DISTINCT "students".id, exams.id AS alias_0 FROM "students" LE
user.students.includes(:exams).ungraded.paginate(:page =>
params[:page]).order("exams.created_at desc")
然而,这导致了一个微妙的问题。在活动记录中的某些地方,该限制使其在学生id上产生了明显的影响,如下所示:
SELECT DISTINCT "students".id, exams.id AS alias_0 FROM "students"
LEFT OUTER JOIN "exams" ON "exams"."student_id" = "students"."id"
WHERE "students"."ready_for_grading" = 't' ORDER BY exams.id LIMIT 10 OFFSET 0;
但是,这可能会导致以下结果:
id | alias_0
----+---------
42 | 256
42 | 257
42 | 260
看到问题了吗?最终,限制开始生效,我们没有得到我们应该得到的那么多学生id,因为我们已经通过选择学生id和考试id用完了它们,即使我们真的只想要考试id用于订购
这是Rails 3.2.1和PostgreSQL 9.1
编辑
我认为现在的情况是paginate使用查询获取学生列表,然后将其提供给第二个查询,但由于左外连接,我们无法为学生获得不同的结果,因此它“填充”了我们现有的10个位置,并且通常会使事情变得混乱。我认为这是某个地方的一个bug,但我不确定该将其锁定在谁身上。好的,我终于找到了答案:
user.students.joins("left outer join exams on exams.student_id = students.id").ungraded.paginate(:page =>
params[:page]).order("exams.created_at desc")
似乎有效。我不知道为什么这比使用“包含”效果更好,但确实如此。我使用了这个相关的解决了我的问题: