【问题标题】:Sequel eager load some associations of single ORM objectSequel eager 加载单个 ORM 对象的一些关联
【发布时间】:2014-08-03 18:36:21
【问题描述】:

我正在为一个小型应用程序构建数据模型,并希望在某些方法中利用预先加载的优势 - 即我事先知道某些关联将被使用的方法。

我已经阅读了the Sequel::Model::Association.eager 方法的指南,但它让我有些困惑。一个典型的例子可能是:

Artist.eager( :albums => :tracks ).all

加载所有 Artist 对象,并预加载所有专辑字段,并预加载所有曲目,仅使用三个查询。到目前为止,一切顺利。

但是假设我想通过其主键加载单个艺术家,并且仍然预先加载专辑 + 曲目(仍然是三个查询,可能比跟踪每个专辑的关联要少得多)?我看不到任何这样的例子。一个小实验给了我

Artist.eager( :albums => :tracks ).where( :id => id ).all.first

这似乎至少有效。我通过调用它确认了急切加载,然后关闭了数据库,并显示我仍然可以访问关联。

但是,我觉得我错过了一些东西。该构造必须将主键传递给where 子句,获得完整的数据集然后要求第一项似乎很尴尬。我正在寻找这样的东西:

Artist.eager( :albums => :tracks )[ id ]

。 . .声明我想要加载单个对象并急切加载它的一些关联的简单方法。

发现我可以像这样创建自定义关联:

def eager_albums
  albums_dataset.eager( :tracks ).all
end

但这很难用,因为代码必须以不同的方式请求关联。

我的问题:我的构造 Artist.eager( :albums => :tracks ).where( :id => id ).all.first 是否像我在 Sequel 中所做的那样认为,我可以做得更好(更简单的代码)吗?

【问题讨论】:

    标签: ruby sequel


    【解决方案1】:

    调用Artist.eager( :albums => :tracks ).where( :id => id ).all.first 获取所有id 等于'id' 的艺术家,然后从结果数组中提取第一个艺术家(调用all 实现数组)。通常,此查询只会返回一个包含单个艺术家的数组。

    直到您实际请求关系 artist.albums 或专辑之外的关联,才会运行其他查询。

    你可以这样做Artist.eager( :albums => :tracks ).where( :id => id ).first

    我使用tactical eager loading plugin,因此几乎没有必要使用 eager,因为它会检测何时从模型实例中使用关联,该模型实例是较大结果集的一部分,并为整个结果集自动。您的查询现在变为Artist[id],或Artist[id].albums.all

    我使用的另一个方便的插件是 association proxies plugin,所以我不必处理使用 association.some_array_methodassociation_dataset.some_ds_method 的问题

    最后,dataset associations plugin 允许您描述从某个模型或模型类开始的查询,并通过关联链接到目标模型,同时允许您在此过程中定义(或不​​定义)约束。

    例如“在过去 2 周内由英国出生的艺术家发行的任何专辑中查找所有长度超过 3 分钟的曲目”:

    Artist.where(country_of_birth: 'UK').albums.where{ release_date > Date.today - 14}.tracks.where{ duration > 3.minutes }.all

    希望这能有所启发。

    【讨论】:

    • 有用的信息,谢谢,但我不确定“直到您实际请求关系艺术家.专辑或专辑之外的关联,才会运行其他查询。”我的查询是正确的 - 我已经运行了我的查询关闭了数据库服务器,然后成功地遍历了 Ruby 中关系中的子对象(诚然,那是我问这个问题的时候,事情可能已更改,或者我的测试可能存在缺陷)。
    • 开箱即用的 eager() 在您请求之前绝对不会执行相关的关联查询。 eager_graph() 是另一种野兽,具有您描述的行为。您可能已经从先前的查询中缓存了关联,或者引用了关联并触发了加载的其他副作用。除非您调用 artist.albums(true),否则关联将被缓存并且不会重新加载,请参阅:sequel.jeremyevans.net/rdoc/files/doc/…
    猜你喜欢
    • 2020-05-16
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2014-10-13
    • 2016-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多