设置
我有一个像这样的 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
...那么它实际上不是一个存款集合,它仍然是一个交易集合,即。这是一个
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 并且它包含您提到的错误。
我从关键的 http://pivotallabs.com/merging-scopes-with-sti-models/ 看到这篇关于在范围内使用 was_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/