根据关联模型中的字段进行ActiveRecord查询

时间:2013-11-20 06:18:42

标签: sql ruby-on-rails activerecord

我有以下数据库关系:

Entry
has_one :math_test_before, class_name: "MathTest"
has_one :math_test_after, class_name: "MathTest"

我想查看entry.math_test_before.score > entry.math_test_after.score

中的每个条目

如何制作一个ActiveRecord查询,允许我参考每个条目的数学考试成绩并进行比较?

2 个答案:

答案 0 :(得分:0)

根据OP提供的the pastebin,以下声明:

Entry.joins(:math_test_before, :math_test_after)
     .where('math_test_before.score > math_test_after.score').all

生成了以下SQL查询:

Entry Load (0.3ms)  SELECT "entries".* FROM "entries" INNER JOIN "math_tests" ON "math_tests"."entry_id" = "entries"."id" INNER JOIN "math_tests" "math_test_afters_entries" ON "math_test_afters_entries"."entry_id" = "entries"."id" WHERE (math_test_before.score > math_test_after.score)

现在写下正确的陈述是微不足道的。这是:

Entry.joins(:math_test_before, :math_test_after)
     .where('math_tests.score > math_test_afters_entries.score').all

但是,当您运行此查询时,您将无法获得所需的结果。这是因为您的关联尚未正确设置。查看您的日志:math_tests表连接到同一外键上的entries表两次,这意味着相同的测试将同时作为测试之前和之后。

您需要对关联设置进行一些更改。首先,您的条目应belong_to到两个MathTest实例,如下所示:

class Entry < ActiveRecord::Base
  belongs_to :math_test_before, :class_name => 'MathTest'
  belongs_to :math_test_after, :class_name => 'MathTest'
end

您还需要通过创建适当的迁移并运行math_test_before_id,将名为math_test_after_idrake db:migrate的列添加到条目表中。之后,编辑您的MathTest类,如下所示:

class MathTest < ActiveRecord::Base
  has_one :before_entry, :class_name => 'Entry', :foreign_key => 'math_test_before_id'
  has_one :after_entry, :class_name => 'Entry', :foreign_key => 'math_test_after_id'
end

提供的查询应该可以正常工作。


OLDER ATTEMPTS :下面列出的第一次和第二次尝试写入此查询失败。它们留在这里是为了记录,以便其他人不会浪费时间尝试这些。

这样的事情应该有效:

Entry.joins(:math_test_before, :math_test_after)
.where('math_test_before.score > math_test_after.score').all

请提供上述声明的输出,即使它没有提供所需的输出。我很担心,因为我从来没有必要使用has_one关联的class_name属性。

<强>更新 看看这个答案:https://stackoverflow.com/a/8588520/563535。根据海报,生成的别名是<assoc_name>_<entity_name_plural>。因此,您的查询应该使用math_test_before_entries.score > math_test_after_entries.score。查看生成的语句将有助于我们进一步明确这一点。

答案 1 :(得分:0)

我最终通过使用多个表继承为每个对象提供了自己的数据库表。