gpt4 book ai didi

ruby-on-rails - Sorbet 找不到 `has_many` 关联方法

转载 作者:行者123 更新时间:2023-12-05 02:42:18 25 4
gpt4 key购买 nike

我有一个 Rails 模型,其中 has_many items:

class Plan < ApplicationRecord
extend T::Sig

has_many :items, dependent: :destroy

before_save do
# hyper simple test method to illustrat problem
puts items
end
end

但是 Sorbet 似乎与 has_many :items 无关。当我运行 Sorbet 类型检查时,出现以下错误:

$ srb tc
app/models/plan.rb:11: Method items does not exist on T.class_of(Plan) https://srb.help/7003
11 | items
^^^^^
Did you mean:
sorbet/rails-rbi/models/plan.rbi:86: Plan::GeneratedAssociationMethods#items
86 | def items; end

Sorbet 的问题的答案是肯定的 - 我的意思是那种方法。困惑从何而来?为什么 RBI 文件中 .items 的定义不能满足 Sorbet 了解此方法定义位置的需求?

最佳答案

好吧,原来这是对 Rails(Ruby?)而不是 Sorbet 的误解。跳过这实际上是冰糕的一个要点,因为它有助于发现和解决这个问题。

问题是,当您将一个 block 传递给 before_save 时, 该 block 在类 ( Plan ) 而不是实例 ( plan ) 上被调用。相反,一个实例被传递给它。

所以取原来的代码:

class Plan < ApplicationRecord
extend T::Sig

has_many :items, dependent: :destroy

before_save do
# hyper simple test method to illustrate problem
puts items
end
end

这将导致执行 Plan.before_save(plan) .在哪里planPlan 的实例.所以在上面的例子中,items正在被凭空拉出来,不会起作用。

两种有效的语法

class Plan < ApplicationRecord
extend T::Sig

has_many :items, dependent: :destroy

before_save do |plan| # <= notice the argument
puts plan.items
end
end

会起作用。

class Plan < ApplicationRecord
extend T::Sig

has_many :items, dependent: :destroy
before_save :put_items

def put_items
puts items
end
end

我不太确定是什么让第二个起作用,无论是 Ruby 魔法还是 Rails 魔法,但有时我喜欢的魔法太多了。

关于ruby-on-rails - Sorbet 找不到 `has_many` 关联方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67705439/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com