简体   繁体   English

在rails 4和postgres中激活记录查询

[英]active record quering in rails 4 and postgres

I have 2 models 我有2个型号

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

Daily, I need update state on Rides with active state having all trips with date attribute < Date.today how to perform this in 1 query? 每日,我需要更新状态的骑行 活动状态所有 行程都有日期属性<Date.today如何在1个查询中执行此操作? i can archive such result using: 我可以使用以下方式存档此类结

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

but it makes huje queries to count trips, eq: 但它会使huje查询计算行程,例如:

    [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]]

.... ....

Add scopes on Ride with a group and having clause. 使用grouphaving子句在Ride上添加范围。 It would check the count of all future trips of a ride and return the rides with 0 count. 它将检查所有未来旅程的计数并返回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

Using a lambda since you had it on the active scope in Trip . 因为你在Trip的活动范围上使用了lambda I am guessing you need to use a different date than Date.today for some queries. 我猜你需要使用与Date.today不同的日期Date.today进行一些查询。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM