如何获得具有多态关联的范围

时间:2017-04-07 16:06:30

标签: ruby-on-rails activerecord ruby-on-rails-5

我正在构建一个Rails 5应用程序,在这个应用程序中我有两个模型。 第一个称为Timeoff,第二个称为Approval。

我希望得到所有没有批准的Timeoff对象。

模特休假

class Timeoff < ApplicationRecord

  scope :not_approved, -> { self.approvals.size > 0 }

  has_many :approvals, as: :approvable, dependent: :destroy

end

审批模式

class Approval < ApplicationRecord

  belongs_to :approvable, polymorphic: true

end

我这样称呼它

Timeoff.not_approved

我收到错误

NoMethodError: undefined method `approvals' for #<Class:0x007f9698587830>

1 个答案:

答案 0 :(得分:2)

您尝试在类上下文中调用approvals,但它实际上属于Timeoff的实例。例如:

Timeoff.approvals # doesn't work
Timeoff.first.approvals # works

这就是您收到undefined method错误的原因。 但我认为你想要一个数据库查询。你可以采取两种方式 - 我知道:

进行两次查询:找到timeoffs approvals,然后使用NOT IN

查询其他查询
timeoff_ids = Approval.where(approvable_type: 'Timeoff').pluck(:approvable_id)
Timeoff.where.not(id: timeoff_ids)

如果您的牌桌很大,这可能会变得很慢。 或者你可以在approvals表上进行连接并过滤到id为null的位置:

Timeoff.joins("LEFT JOIN approvals ON timeoffs.id = approvals.approvable_id AND approvals.approvable_type = 'Timeoff'").where("approvals.id IS NULL")

这也应该有效,而且可能更快 - 但您应该使用自己的数据来衡量。

另外,请看一下这个问题:How to select rows with no matching entry in another table?对第二个查询以及其他一些解决方法有完整的解释。