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的第二个范围可能是一个好主意。 –