0

我有2種型號活動記錄quering

Class Ride 
    has_many :trips 

    #state (string: active or expired) 
end 

Class Trip 
    #date (Date attribute) 
    scope :active, -> (start_at = Date.today) { where("trips.date >= ?", [Date.today, start_at].max) } 
end 

日報,我需要遊戲機活躍狀態所有車次與日期屬性< Date.today更新狀態 如何在1個查詢中執行此操作? 我可以使用歸檔這樣的結果:

Ride.with_active_state.select{|r| r.trips.active.size ==0} 

但它使胡耶查詢計數人次,EQ:

[1] pry(main)> Ride.with_active_state.select{|r| r.trips.active.size ==0} 
    (7.3ms) SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='rides' 
    Ride Load (1.6ms) SELECT "rides".* FROM "rides" WHERE (rides.workflow_state = 'active') 
    (2.9ms) SELECT f_geometry_column,coord_dimension,srid,type FROM geometry_columns WHERE f_table_name='trips' 
    (1.3ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 9]] 
    (0.7ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 10]] 
    (0.7ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 11]] 
    (0.7ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 12]] 
    (0.8ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 13]] 
    (0.8ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 14]] 
    (0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 15]] 
    (0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 16]] 
    (0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 17]] 
    (0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 18]] 
    (0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 19]] 
    (0.5ms) SELECT COUNT(*) FROM "trips" WHERE "trips"."ride_id" = $1 AND (trips.date >= '2013-09-24') [["ride_id", 20]] 

....

回答

2

Ride添加範圍與grouphaving條款。它將檢查所有未來旅行的次數並返回0次計數。

Class Ride 

    scope :active_state, where(state: "active") 
    scope :with_nonactive_trips, -> (start_date = Date.today){ joins(:trips). 
            group("rides.id"). 
            having(["sum(trips.date > ?) = 0",start_date]) } 

end 

Ride.active_state.with_nonactive_trips 
# returns All the rides with state == active, alteast one trip and having no trips with date > Date.today 

使用lambda,因爲你有機會在Trip活動範圍。我猜你需要對某些查詢使用與Date.today不同的日期。

+0

騎可以有2個旅程,一個有過期日期,另一個有未來日期。在這種情況下,它不應該在這個查詢中被選中... – Danil

+0

更新了答案 – tihom

+0

一些解釋,爲什麼你需要使用lambda的第二個範圍可能是一個好主意。 –