gpt4 book ai didi

ruby-on-rails - STI 子类范围的未定义方法错误

转载 作者:行者123 更新时间:2023-12-04 06:04:54 25 4
gpt4 key购买 nike

设置

我有一个像这样的 STI 设置:

class Transaction < ActiveRecord::Base
belongs_to :account

scope :deposits, -> { where type: Deposit }
end

class Deposit < Transaction
scope :pending, -> { where state: :pending }
end

class Account < ActiveRecord::Base
has_many :transactions
end

如果我调用:

> a = Account.first
> a.transactions.deposits

...然后我得到了我所期望的,Deposit 实例的集合,但是如果我查看返回的类:

> a.transactions.deposits.class

...那么它实际上不是 Deposit 集合,它仍然是 Transaction 集合,即。这是一个 Transaction::ActiveRecord_AssociationRelation

问题

所以,对于这个问题,如果我想调用该集合上的 Deposit 范围之一,它会失败:

> a.transactions.deposits.pending
NoMethodError: undefined method `pending' for #<Transaction::ActiveRecord_Associations_CollectionProxy:0x007f8ac1252d00>

我检查过的东西

我已经尝试将范围更改为 Deposit.where... 没有效果,也尝试将范围更改为 Deposit.unscoped.where... 实际上返回正确的集合对象,它剥离了所有范围,所以我丢失了查询的 account_id=123 部分,所以它在那一侧失败。

我已经检查过了,Rails 4.1 和 4.2 都存在这个问题。感谢您提供有关如何完成这项工作的任何指示。

我知道有一个解决方法,但是...

我知道我可以通过将 has_many :deposits 添加到 Account 来解决这个问题,但我正在努力避免这种情况(实际上我有很多关联表和许多不同的交易子类,我试图避免添加许多需要的额外关联)。

问题

我怎样才能让 deposits 范围返回的内容实际上是一个 Deposit::ActiveRecord_Association... 以便我可以从 Deposit 链接我的范围类?

最佳答案

我在这里为您的问题创建了一个独立测试:https://gist.github.com/aalvarado/4ce836699d0ffb8b3782#file-sti_scope-rb它有你提到的错误。

我是从 pivotal http://pivotallabs.com/merging-scopes-with-sti-models/ 看到这篇文章的关于在范围内使用 were_values 来获取所有条件。然后我在 unscope 上使用它们来强制使用预期的类,基本上是这样的:

  def self.deposits
conditions = where(nil).where_values.reduce(&:and)
Deposit.unscoped.where(conditions)
end

这个测试断言它返回一个Deposit::ActiveRecord_Relation https://gist.github.com/aalvarado/4ce836699d0ffb8b3782#file-sti_scope2-rb

更新

如果你愿意,你也可以把它写成一个范围:

  scope :deposits, -> { Deposit.unscoped.where where(nil).where_values.reduce &:and }

关于ruby-on-rails - STI 子类范围的未定义方法错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28711074/

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