2016-02-10 39 views
2

活動有屬性:start_date,:end_date查詢爲參加社團在軌

發票有屬性:start_date,:end_date

campaign.rb

has_many:invoices 

invoice.rb

belongs_to:campaign 

我想所有這些cmapaigns的start_date是小於當前日期ANDend_date介於campaign.invoices.last.created..current_date之間

我如何查詢?

+0

請告訴我們,你嘗試過什麼? – mudasobwa

+0

Campaign.joins(:invoices).where(「campaigns.start_date <?and campaigns.end_date>?」,Time.current,????????) –

回答

3

試試這個:

Compaign.joins(:invoices) 
      .where("compaigns.start_date < :today AND compaigns.end_date < :today", today: Date.today) 
      .group("compaigns.id") 
      .having("compaigns.end_date > MAX(invoices.created_at)") 
2

我從來沒有使用Rails魔術來執行對數據庫的或多或少複雜的請求。它總是導致劇烈的開銷,N + 1個查詢或者一些意想不到的處罰。這裏是普通的老好版本的SQL執行此任務:

Campaign.connection.execute <<-SQL 
    SELECT campaigns.*, last_invoice_date 
    FROM campaigns 
    JOIN (
     SELECT invoices.campaign_id AS campaign_id, 
       MAX(invoices.started) AS last_invoice_date 
     FROM invoices 
     GROUP BY invoices_campaign_id 
    ) AS last_invoices 
    ON (last_invoices.campaign_id = campaigns.id) 
    WHERE campaigns.start_date < NOW() 
     AND campaigns.end_date < NOW() 
     AND campaigns.end_date >= last_invoices.last_invoice_date 
SQL.to_a 

上面沒有明顯的原因進行測試,但它應該工作無論是作爲是或略有修改。

1
campaigns = Campaign.where("DATE(start_date) < ?", Date.today).includes(:invoices) 

invoices = campaigns.each do |campaign| 
       campaign.invoices.where("Date(campaigns.end_date)" BETWEEN campaign.invoices.last.created_at.to_date AND Date.today) 
      end 

invoices.map(&:campaign) 
+0

'campaigns.each'可能需要很長時間才能執行。這是一個很糟糕的做法,這就是我的意思的一個確切例子「它總是會導致大量開銷,N + 1個查詢或者一些意想不到的處罰。」 – mudasobwa

+0

這就是爲什麼Rails提供急切加載以避免N + 1查詢。 – Rubysmith

+0

真的嗎?再次說明:上面代碼片段中的'campaigns.each'將永遠執行,比如1B記錄。 – mudasobwa