的财产ActiveRecord的范围,我有三个型号Component
,这是与对方喜欢这样关联Version
和User
:Rails的:根据孩子
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)
是没有良好的相反,因为它返回它既有未经批准和认可的版本中,当我只希望这只有具有u组件组件未批准的版本(或根本没有版本)。
我也试过将SQL查询传递给joins
,其中包括OUTER JOIN
而不是INNER,但他们没有给我我想要的,他们正在扩展我对SQL的有限理解。
如何获得我需要的查询?
(我使用的是Postgres和Rails 3.2.13,在它的问题的情况下。)
作品魅力!虽然第二个例子没有关闭''''。但是,我怎样才能定义'未批准'范围呢? – GMA
使用“NOT EXISTS”或“NOT IN”。看来PostgreSQL优化器不如我想的那么好,所以坚持使用第二版。作为奖励,它更容易理解。顺便说一句,你应该考虑学习一点SQL,通过子查询,你将准备好解决98%的Web开发中出现的数据库访问任务。 – synapse