【问题标题】:How do I chain multiple models to reduce the number of SQL queries如何链接多个模型以减少 SQL 查询的数量
【发布时间】:2023-03-15 21:30:01
【问题描述】:

我正在尝试检查学生是否尝试了指定的测试。我想链接相关模型以将查询数量减少到只有 1。以下是我的模型:

class Test < ActiveRecord::Base
  has_many   :assigns
  has_many   :attempts
  belongs_to :topic
end

class Topic < ActiveRecord::Base
  has_many    :tests
  has_many    :attempts
  has_many    :assigns, through: :test
end

class Assign < ActiveRecord::Base
  belongs_to  :test
  belongs_to  :student
  has_many    :attempts
end

class Attempt < ActiveRecord::Base
  belongs_to  :test
  belongs_to  :topic
  belongs_to  :assign
  belongs_to  :student
end

我想检查特定学生(id:100)是否尝试了指定的测试,并检索其他详细信息,例如测试的主题名称。到目前为止,我有这样的事情:

ta = Assign.includes(:test => {:topic => :attempts})

这允许我在单个查询中检索详细信息,例如 test_name、topic_name、何时分配等。如何在同一查询中还包括 student_id: 100 的尝试记录?就我现在所拥有的,当我检索学生的尝试详细信息时,正在生成一个全新的查询。

我想要的是类似以下的东西,而不必再次接触数据库:

ta.test.attempts.where(student_id: 100)

如何只用一个查询完成所有这些操作?

【问题讨论】:

  • test_ 前缀是assigntopicattempt 所必需的吗?这里发生的事情太多了,有点难以阅读。你能放一张ER图吗?
  • @lusketeer 为清楚起见删除了 test_。

标签: sql ruby-on-rails activerecord


【解决方案1】:

好的,既然你想从所有连接的表中获取各种信息,所以你必须从头开始连接它们。

Attempt.joins(:topic, :test, :assign)

然后你可以用student_id过滤它

.where("attempts.student_id" =&gt; 100)

最后是你想要的字段

.select("attempts.id as attempt_id, tests.name as test_name, topics.name as topic_name, assigns.created_at as assigned_at")

总结

Attempt
    .joins(:topic, :test, :assign)
    .where("attempts.student_id" => 100)
    .select("attempts.id as attempt_id, tests.name as test_name, topics.name as topic_name, assigns.created_at as assigned_at")

【讨论】:

    猜你喜欢
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多