范围是否与自身的可选HAS_ONE协会(Scope for an optional has_one

2019-10-19 03:34发布

我有一个模型缩进。 在这我使用STI。 缩进可以有两种类型的买卖。 在购买类我使用一个可选的HAS_ONE关联。

class Purchase < Indent
    has_one :sale , :class_name => 'Sale', :foreign_key => 'linked_indent_id'
    # Make it work.  
    scope :unsold, lambda {includes(:sale).where('id not in (select distinct linked_indent_id from indents)')}
end

class Sale < Indent
   belongs_to :purchase , :class_name => 'Purchase', :foreign_key => 'linked_indent_id'
end

我只需要使用它我可以找到所有这些都没有关联到他们销售的采购采购类范围。

我使用Rails 3.2和Postgres数据库。

更新:

这是越来越生成查询如下。

 SELECT "indents".* FROM "indents" WHERE "indents"."type" IN ('Purchase') AND 
 (id not in (select distinct linked_indent_id from indents)) ORDER BY indent_date DESC

查询下面的部分是工作的罚款。

=# select distinct linked_indent_id from indents;

 linked_indent_id 
 ------------------

        15013
        15019
       (3 rows)

这也是工作的罚款。

SELECT "indents".* FROM "indents" WHERE "indents"."type" IN ('Purchase') AND
(id not in (15013, 15019)) ORDER BY indent_date DESC

我失去了在查询中的这两部分耦合是什么?

Answer 1:

我第一次用的术语迷惑purchasesale 。 但是,你的更新,我相信帮助我理解这个问题更多。

所以,我的理解是什么,未售出的是减去销售采购。 下面应该给你的列表:

scope :unsold, lambda {includes(:sale).select { |p| !p.sale.present? } }

更新:

这里发生了什么的简要说明:

范围并没有真正做数据库中的所有工作。 它SQL选择所有的采购,包括加入了销售第一的。 这使你在所有记录purchases表。 那么这个范围回落到Ruby Array上的select方法。 该方法返回的所有采购p没有sale是通过否定与销售采购完成。

希望这清除了在什么范围做了一些。

更新2:

作用域这是可链接!

scope :unsold, lambda { where('id not in (?)', Sale.pluck(:linked_indent_id)) }

在此范围内的id不在购买第Salelinked_indent_id选择。



Answer 2:

Rails的安永数据库为中心的方式来做到这一点:

scope :sold, -> { joins(:sale) }
scope :unsold, -> { includes(:sale).where(sales: {linked_indent_id: nil}) }

(请注意,您必须在使用该表名where条款,而不是关系名,即“销售”,而不是“销售”。)



文章来源: Scope for an optional has_one association with itself