From cabc7156d166675add51ed6bb597720ef0ae73ef Mon Sep 17 00:00:00 2001 From: Akinori MUSHA Date: Wed, 19 Apr 2017 19:25:14 +0900 Subject: [PATCH] Protect the latest event from automatic deletion when using MySQL This is a workaround for #1940. --- app/models/event.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/app/models/event.rb b/app/models/event.rb index 410bc8b8..09c62252 100644 --- a/app/models/event.rb +++ b/app/models/event.rb @@ -28,6 +28,15 @@ class Event < ActiveRecord::Base where("expires_at IS NOT NULL AND expires_at < ?", Time.now) } + case ActiveRecord::Base.connection + when ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter + # Protect the Event table from InnoDB's AUTO_INCREMENT Counter + # Initialization by always keeping the latest event. + scope :to_expire, -> { expired.where.not(id: maximum(:id)) } + else + scope :to_expire, -> { expired } + end + scope :with_location, -> { where.not(lat: nil).where.not(lng: nil) } @@ -72,9 +81,11 @@ class Event < ActiveRecord::Base # Look for Events whose `expires_at` is present and in the past. Remove those events and then update affected Agents' # `events_counts` cache columns. This method is called by bin/schedule.rb periodically. def self.cleanup_expired! - affected_agents = Event.expired.group("agent_id").pluck(:agent_id) - Event.expired.delete_all - Agent.where(:id => affected_agents).update_all "events_count = (select count(*) from events where agent_id = agents.id)" + transaction do + affected_agents = Event.to_expire.group("agent_id").pluck(:agent_id) + Event.to_expire.delete_all + Agent.where(id: affected_agents).update_all "events_count = (select count(*) from events where agent_id = agents.id)" + end end protected