【发布时间】:2013-08-30 02:22:29
【问题描述】:
我有三个模型Component、Version 和User,它们相互关联,如下所示:
class Component < ActiveRecord::Base
has_many :versions, class_name 'ComponentVersion'
end
class ComponentVersion < ActiveRecord::Base
belongs_to :component
belongs_to :approver, class_name: 'User'
end
class User < ActiveRecord::Base
end
我想在Component 上创建两个作用域:approved 和 unapproved。当一个组件至少有一个被批准的version 时,它被“批准”,而一个版本在其approver_id 不是nil 时被批准。所以Component.approved 应该返回所有批准的组件,Component.unapproved 应该返回所有未批准的版本。
不幸的是,我不知道该怎么做。
我可以很容易地在 ComponentVersion 上定义范围:
class ComponentVersion < ActiveRecord::Base
belongs_to :component
belongs_to :approver, class_name: 'User'
scope :approved, -> { where('approver_id IS NOT NULL') }
scope :unapproved, -> { where('approver_id IS NULL') }
end
然后在控制台Component.joins(:version).merge(ComponentVersion.approved) 给了我一些接近我想要的Component.approved 的东西,除了它包含重复项(如果一个组件有多个批准的版本,它会被多次返回。)
而Component.joins(:version).merge(ComponentVersion.unapproved) 则相反,因为它返回的组件同时具有未经批准和批准的版本,而我只想要 仅 具有未经批准的版本(或根本没有版本)的组件。
我还尝试将包含 OUTER JOIN 而不是 INNER 的 SQL 查询传递给 joins,但它们并没有给我想要的东西,而且它们扩展了我对 SQL 的有限理解。
如何获得我需要的查询?
(我使用的是 Postgres 和 Rails 3.2.13,以防万一。)
【问题讨论】:
标签: ruby-on-rails activerecord scope named-scope