2016-08-26 20 views
0

我试图通过续集宝石的eager方法渴望加载关系数据,同时使用with_sql来定义用于查询的SQL(这是一个相当复杂的查询)。急切的加载根本不起作用。相反,它为每个返回的行生成每个关系的单个查询,这正是我试图避免的。下面是一些代码:当使用with_sql时,续集是否可以加载关系?

class Foo 
    many_to_one :rel1 
    one_to_many :rel2 
    def self.bar 
    sql = 'some complex sql' 
    Foo.with_sql(sql).eager(:rel1, :rel2) 
    end 
end 

的问题是,当我叫Foo.bar,REL1和REL2的急切装载的好像忽略了。我通过观看日志验证了这一点 - 对于with_sql调用返回的每一行,它会生成2个查询 - 一个用于rel1,另一个用于rel2。

可能值得注意的是sql包含3个连接。

这是使用with_sql的限制。有没有办法解决这个限制?

+0

你为什么使用'eager'宝石? SQL应该自己“急切加载”。你可以做的一件事是用一个简单的查询更新问题,也许只有一个连接。 –

回答

0

原来这不是with_sql的限制。问题在于有一个limit被添加到查询下游,并强制加载被忽略。调用Foo.bar工作正常,但如果通过limit(<integer>)限制输出,它必然会否定任何急切的加载,因为sql查询本身包含多个连接。我对Sequel文档的理解表明,在这种情况下,急切的加载无法工作。如果情况并非如此,我很乐意听到它。

+0

虽然有趣的是,Sequel的文档特别声明“Eager也适用于有限的数据集......”所以这个谜仍然存在。 – user2571294

+0

最后得到这个排序。您可以使用预先加载的限制,但调用顺序似乎很重要。如果我这样做:'with_sql(sql).limit(per_page).offset(per_page *(page - 1)).eager(:rel1,:rel2).all',它的工作原理。如果我在调用'eager'之后放置'limit'和'offset',它就不起作用。有趣。无论如何,只要超级开心就能最终实现这一目标。 – user2571294

0

请注意,Sequel中的eager使用每个关联的查询进行热切加载。您可能想要使用eager_graph,它使用连接。您可以使用eager_graphwith_sql,但您可能还需要使用set_graph_aliases来告诉Sequel如何将每行分割为单独的对象。另外,请确保您在数据集上调用all以获得结果,但如果不预先记录所有记录,则无法加载数据集。

在限制方面,只要您调用all就可以加载一个使用limit的数据集,但请注意,如果您急于加载* _many关联,它通常不会执行您想要的操作。

相关问题