我有以下数据库关系:
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查询,允许我参考每个条目的数学考试成绩并进行比较?
答案 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_id
和rake 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)
我最终通过使用多个表继承为每个对象提供了自己的数据库表。