From 93b05616c9172777a4ea103a2fc5c87fda453668 Mon Sep 17 00:00:00 2001
From: Mark Chao <mchao@gitlab.com>
Date: Wed, 25 Jul 2018 16:08:54 +0800
Subject: [PATCH] Reduce query for update_dates to 1 select

---
 ee/app/models/ee/epic.rb    | 11 +++++++++--
 ee/spec/models/epic_spec.rb | 30 +++++++++++++++++++++++-------
 2 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/ee/app/models/ee/epic.rb b/ee/app/models/ee/epic.rb
index 639da374389..bdb517b3f9b 100644
--- a/ee/app/models/ee/epic.rb
+++ b/ee/app/models/ee/epic.rb
@@ -111,8 +111,15 @@ module EE
     alias_attribute(:due_date, :end_date)
 
     def update_dates
-      self.start_date = compute_start_date
-      self.due_date = compute_due_date
+      if !start_date_is_fixed? || !due_date_is_fixed?
+        milestone_dates = issues
+          .joins(:milestone)
+          .pluck('MIN(milestones.start_date)', 'MAX(milestones.due_date)')
+          .first
+      end
+
+      self.start_date = start_date_is_fixed? ? start_date_fixed : milestone_dates[0]
+      self.due_date = due_date_is_fixed? ? due_date_fixed : milestone_dates[1]
       save if changed?
     end
 
diff --git a/ee/spec/models/epic_spec.rb b/ee/spec/models/epic_spec.rb
index ca355931446..e1917926b01 100644
--- a/ee/spec/models/epic_spec.rb
+++ b/ee/spec/models/epic_spec.rb
@@ -165,17 +165,33 @@ describe Epic do
 
     context 'fixed date is not set' do
       subject { create(:epic, start_date: nil, end_date: nil) }
-      let(:start_date) { Date.new(2001, 1, 1) }
-      let(:due_date) { Date.new(2002, 1, 1) }
+      let(:milestone1) {
+        create(
+          :milestone,
+          start_date: Date.new(2000, 1, 1),
+          due_date: Date.new(2000, 1, 10)
+        )
+      }
+      let(:milestone2) {
+        create(
+          :milestone,
+          start_date: Date.new(2000, 1, 3),
+          due_date: Date.new(2000, 1, 20)
+        )
+      }
+
+      before do
+        epic_issue1 = create(:epic_issue, epic: subject)
+        epic_issue1.issue.update(milestone: milestone1)
+        epic_issue2 = create(:epic_issue, epic: subject)
+        epic_issue2.issue.update(milestone: milestone2)
+      end
 
       it 'updates to milestone dates' do
-        expect(subject).to receive(:start_date_from_milestones).and_return(start_date)
-        expect(subject).to receive(:due_date_from_milestones).and_return(due_date)
-
         subject.update_dates
 
-        expect(subject.start_date).to eq(start_date)
-        expect(subject.due_date).to eq(due_date)
+        expect(subject.start_date).to eq(milestone1.start_date)
+        expect(subject.due_date).to eq(milestone2.due_date)
       end
     end
   end
-- 
2.30.9