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

时间:2013-09-23 21:58:07

标签: ruby-on-rails postgresql ruby-on-rails-4 rails-activerecord

我有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

每日,我需要使用日期属性< 所有 行程的 Rides 处于活动状态的更新状态Date.today 如何在1个查询中执行此操作? 我可以使用以下方式存档此类结果:

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

但它会使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]]

....

1 个答案:

答案 0 :(得分:2)

使用Ridegroup子句在having上添加范围。它将检查所有未来旅程的计数并返回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。我猜你需要使用与{{1}}不同的日期进行某些查询。