【问题标题】:Rails: using eager_loading scope gives an errorRails:使用 eager_loading 范围会出错
【发布时间】:2021-04-16 16:24:04
【问题描述】:

我正在处理Rails 项目,并尝试在我的模型中创建scope,而不是在需要时创建instance methodpreload 该范围。但是我对示波器不是很有经验,并且无法使其正常工作,或者可能是我做错了。我有一个实例方法做同样的事情,但注意到一些 n+1 问题。我受到这篇文章How to preload Rails scopes 的启发,并想尝试使用范围。

(作为旁注,我使用的是ancestry gem)

我尝试了三种不同的方法来创建范围。它们都适用于 Channel.find_by(name: "Travel").depth但错误适用于 Channel.includes(:depth)eager_load

第一次尝试

has_one :depth, -> { parent ? (parent.depth+1) : 0 }, class_name: "Channel"

第二次尝试

has_one :depth, -> (node) {where("id: = ?", node).parent ? (node.parent.depth+1) : 0 }, class_name: "Channel"

第三次尝试

has_one :depth, -> {where("id: = channels.id").parent ? (parent.depth+1) : 0 }, class_name: "Channel"

这三个在控制台中都可以正常工作:

Channel.find_by(name: "Travel").depth 
Channel Load (0.4ms)  SELECT "channels".* FROM "channels" WHERE "channels"."name" = $1 LIMIT $2  [["name", "Travel"], ["LIMIT", 1]]
=> 2

..但是

Channel.includes(:depth) 为每个范围(1st、2nd、3rd)提供三个不同的错误

第一个范围的错误:

NameError (undefined local variable or method `parent' for #<Channel::ActiveRecord_Relation:0x00007fdf867832d8>)

第二个范围的错误:

ArgumentError (The association scope 'depth' is instance dependent (the scope block takes an argument). Preloading instance dependent scopes is not supported.)

第三个范围的错误:

Object doesn't support #inspect

我做错了什么?或者,最好的方法是什么?感谢您的宝贵时间和帮助。

【问题讨论】:

    标签: ruby-on-rails rails-activerecord


    【解决方案1】:

    我认为.depth 方法返回的不是关联记录的整数值。急切加载是使用尽可能少的查询来加载Model.find 返回的对象的关联记录的机制。

    如果您想加快depth 方法的速度,您需要启用:cache_depth 选项。根据祖先 gem 文档:

    :cache_depth           
       Cache the depth of each node in the 'ancestry_depth' column(default: false)
       If you turn depth_caching on for an existing model:
       - Migrate: add_column [table], :ancestry_depth, :integer, :default => 0
       - Build cache: TreeNode.rebuild_depth_cache!
    

    在您的模型中:

    class [Model] < ActiveRecord::Base
       has_ancestry, cache_depth: true
    end
    

    【讨论】:

    • 谢谢@Juan。我最终在不使用深度的情况下采取了不同的方法。但想试试你的答案。
    猜你喜欢
    • 2020-08-13
    • 1970-01-01
    • 2015-10-16
    • 2020-03-26
    • 2017-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-27
    相关资源
    最近更新 更多