【发布时间】:2021-04-16 16:24:04
【问题描述】:
我正在处理Rails 项目,并尝试在我的模型中创建scope,而不是在需要时创建instance method 和preload 该范围。但是我对示波器不是很有经验,并且无法使其正常工作,或者可能是我做错了。我有一个实例方法做同样的事情,但注意到一些 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