为什么ActiveRecord错误地翻译SQL命令?

时间:2014-07-16 23:04:45

标签: ruby-on-rails postgresql rails-activerecord will-paginate active-record-query

我相信ActiveRecord::Querying搞砸了postgresql命令的翻译。结果返回不同的列然后我期望。任何人都可以帮我找出原因吗?

这项工作(POSTGRES)

SELECT 
quick_tests.id, quick_tests.status, name, 
started_at, array_agg(quick_test_agents.agent_id) as quick_test_agent_ids
FROM quick_tests
JOIN quick_test_agents ON quick_tests.id = quick_test_agents.quick_test_id
GROUP BY quick_tests.id
ORDER BY quick_tests.id desc;

我试图通过这样做来对所有QuickTest进行分页:( quick_test到quick_test_agent是一对多)

tests = QuickTest.paginate :select => 'quick_tests.id,
                                       quick_tests.name,
                                       quick_tests.status,
                                       quick_tests.started_at,
                  array_agg(quick_test_agents.agent_id) as quick_test_agent_ids',
                           :page => current_page,
                           :per_page => page_size,
                           :joins => :quick_test_agent,
                           :group => 'quick_tests.id',

现在问题是QuickTest.paginate没有返回quick_test_agents.agent_id,它返回quick_test_agents.id。

查看日志打印输出,它似乎被错误地翻译了:

QuickTest Load (57.6ms)  SELECT quick_tests.id, quick_tests.name, quick_tests.status,
 quick_tests.started_at, array_agg(quick_test_agents.agent_id) as quick_test_agent_ids FROM "quick_tests" INNER JOIN "quick_test_agents" ON "quick_test_agents"."quick_test_id" = "quick_tests"."id" 
DEBUG    SQL (70.2ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE "quick_test_agents"."quick_test_id" = 889
DEBUG    SQL (66.4ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE "quick_test_agents"."quick_test_id" = 885
DEBUG    SQL (58.3ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE "quick_test_agents"."quick_test_id" = 883
DEBUG    SQL (56.5ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE "quick_test_agents"."quick_test_id" = 882
DEBUG    SQL (52.4ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE "quick_test_agents"."quick_test_id" = 881
DEBUG    SQL (54.6ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE  "quick_test_agents"."quick_test_id" = 880
DEBUG    SQL (52.6ms)  SELECT "quick_test_agents".id FROM "quick_test_agents" WHERE "quick_test_agents"."quick_test_id" = 879

应该选择quick_test_agents.agent_id

SELECT "quick_test_agents".agent_id FROM "quick_test_agents"...

为什么会这样?

1 个答案:

答案 0 :(得分:1)

问题在于别名!

此语句将数组聚合列别名为quick_test_agent_ids:

array_agg(quick_test_agents.agent_id) as quick_test_agent_ids

现在,这可以在postgres中运行,但在ActiveRecord中这已经搞砸了。不知怎的,别名`quick_test_agent_ids'导致ActiveRecord相信它实际上正在寻找quick_test_agents.id。

如果我更改了别名语句,它可以工作:

    array_agg(quick_test_agents.agent_id) as quick_testSSS_agent_ids
    array_agg(quick_test_agents.agent_id) as agent_ids

<强> TL; DR

小心别名,他们可能搞砸了你