mysql - Rails 5 左外连接使用 includes() 和 where()

标签 mysql ruby-on-rails activerecord left-join ruby-on-rails-5

我有一段时间使用 includes() 和 where() 获得预期的行为。

我想要的结果:
- 所有学生(即使他们签到为零)
- 在图书馆签到

我得到的结果:
- 只有在图书馆签到的学生
- 所有学生在图书馆签到


目前我的代码基于此: http://edgeguides.rubyonrails.org/active_record_querying.html#specifying-conditions-on-eager-loaded-associations

它描述了我想要的行为:

Article.includes(:comments).where(comments: { visible: true })

If, in the case of this includes query, there were no comments for any articles, all the articles would still be loaded.

我的代码:

@students = Student.includes(:check_ins)
                    .where(check_ins: {location: "Library"})
                    .references(:check_ins)

.

class CheckIn < ApplicationRecord
  belongs_to :student
end

.

class Student < ApplicationRecord
  has_many :check_ins, dependent: :destroy
end

生成的 SQL 查询:

SELECT "students"."id" AS t0_r0,"check_ins"."id" AS t1_r0, "check_ins"."location" AS t1_r1, "check_ins"."student_id" AS t1_r6 FROM "students" LEFT OUTER JOIN "check_ins" ON "check_ins"."student_id" = "students"."id" WHERE "check_ins"."location" IN ('Library')

这个 SQL 查询给出了我想要的连接行为:

SELECT first_name, C.id FROM students S LEFT OUTER JOIN check_ins C ON C.student_id = S.id AND location IN ('Library');

最佳答案

尝试了一种将 Scopes 与关系结合使用的新方法,期望预加载所有内容并将其过滤掉,但令我惊喜的是,Scopes 实际上为我提供了我想要的确切行为(一直到预加载)。

结果如下:

这个 ActiveRecord 调用会拉取完整的学生列表并立即加载签到:

@students = Student.all.includes(:check_ins)

可以在 has_many 声明中限制 check_ins 的范围:

Class Student < ApplicationRecord
    has_many :check_ins, -> {where('location = 'Library'}, dependent: :destroy
end

产生两个干净、高效的查询:

  Student Load (0.7ms)  SELECT "students".* FROM "students"
  CheckIn Load (1.2ms)  SELECT "check_ins".* FROM "check_ins" WHERE location = 'Library') AND "check_ins"."student_id" IN (6, 7, 5, 3, 1, 8, 9, 4, 2)


宾果!

附注你可以在这里阅读更多关于使用关联范围的信息:
http://ducktypelabs.com/using-scope-with-associations/

关于mysql - Rails 5 左外连接使用 includes() 和 where(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40000148/

相关文章:

ruby-on-rails - 使用给定对象在数据库中查找下一个 ActiveRecord 模型对象

ruby-on-rails - 同一模型之间的 Ruby 关系

mysql - 如何在 Ruby on Rails 中使用 LIKE 查询

ruby-on-rails - 获取十进制数的小数部分

sql - 复杂的 Rails 查询 - 联合?子选择?我还能使用 named_scope 吗?

ruby-on-rails - 将 SOAP 与 Ruby 结合使用的最佳方式是什么?

ruby-on-rails - 获取按唯一字段值分组的最新行

mysql - 在MySql中按组计算唯一记录

MySQL 检查数据库是否存在

java - Mysql 更新似乎有效,但抛出语句关闭错误