如何从has_many关系的范围返回单个值?

时间:2018-03-16 02:53:02

标签: ruby-on-rails rails-activerecord

如何从此范围返回单个记录?我试过两种方式。

class Subscription < ApplicationRecord
  has_many :invoices, dependent: :destroy

class Invoice < ApplicationRecord
  belongs_to :subscription

  scope :current, -> do  
    # where(paid: nil).order(:created_at).last
    where(paid: nil).order(created_at: :desc).limit(1).first
  end

第一种方法是正确添加order by ... desc limit 1,但是它会执行另一个没有where条件的查询!

  

IRB(主):004:0&GT; s.invoices.current
  发票加载(22.0ms)选择“发票”。* FROM“发票”WHERE“发票”。“subscription_id”= $ 1 AND “发票”。“付款”IS NULL ORDER BY“发票”。“ created_at“ DESC LIMIT $ 2 [[”subscription_id“,16],[”LIMIT“,1]]
  发票加载(2.0ms)SELECT“发票”。* FROM“发票”WHERE“发票”。“subscription_id”= $ 1 [[“subscription_id”,16]]
  =&GT; #&lt; ActiveRecord :: AssociationRelation [#&lt;发票ID:8,subscription_id:16,user_id:21,付款:“2018-03-15”,created_at:“2018-03-14 22 :42:48" &GT;]&GT;

第二种方式也会进行另一次查询,删除正确的结果。

  

IRB(主):007:0&GT; s.invoices.current   
  发票加载(2.0ms)SELECT“发票”。* FROM“发票”WHERE“发票”。“subscription_id”= $ 1 AND“发票”。“付款”IS NULL   ORDER BY“发票”。“created_at”DESC LIMIT $ 2 [[“subscription_id”,16],[“LIMIT”,1]]   
  发票加载(2.0ms)SELECT“发票”。* FROM“发票”WHERE“发票”。“subscription_id”= $ 1 [[“subscription_id”,16]]   
  =&GT; #&lt; ActiveRecord :: AssociationRelation [#&lt;发票ID:8,subscription_id:16,user_id:21,付款:“2018-03-15”,created_at:“2018-03-14 22 :42:48" &GT;]&GT;

另外,我如何才能获得记录,而不是ActiveRecord::AssociationRelation

Ruby 5.0.6

2 个答案:

答案 0 :(得分:1)

您可以尝试以下方式:

class Invoice < ApplicationRecord
  belongs_to :subscription 

  class << self 

    def for_subscription(subscription)
      where(subscription: subscription)
    end

    def unpaid
      where(paid: nil)
    end

    def newest
      order(created_at: :desc).first 
    end

  end

end

如果你有一个名为Subscription @subscription的实例,你可以使用:

Invoice.unpaid.for_subscription(@subscription).newest

我认为应该只触发一个查询,并且应该返回invoice个实例。

答案 1 :(得分:-1)

我用

替换了范围
  def self.current
    where(paid: nil).order(:created_at).last
  end

它有效。但是我不知道为什么,因为这个方法在Invoice类,而关系是ActiveRecord::Associations::CollectionProxy类。我希望我知道它为什么有效。我希望我知道为什么范围不起作用并执行两个查询。