Commit 63a2a54a authored by Mark Chao's avatar Mark Chao

Query using ActiveRecord so columns are casted in correct types

parent 5703c9fb
...@@ -2,22 +2,25 @@ ...@@ -2,22 +2,25 @@
module Epics module Epics
class DateSourcingMilestonesFinder class DateSourcingMilestonesFinder
FIELDS = [:id, :start_date, :due_date].freeze
ID_INDEX = FIELDS.index(:id)
START_DATE_INDEX = FIELDS.index(:start_date)
DUE_DATE_INDEX = FIELDS.index(:due_date)
def self.execute(epic_id) def self.execute(epic_id)
sql = <<~SQL results = Milestone.joins(issues: :epic_issue).where(epic_issues: { epic_id: epic_id }).joins(
SELECT milestones.id, milestones.start_date, milestones.due_date FROM milestones <<~SQL
INNER JOIN issues ON issues.milestone_id = milestones.id INNER JOIN (
INNER JOIN epic_issues ON epic_issues.issue_id = issues.id SELECT MIN(milestones.start_date) AS start_date, MAX(milestones.due_date) AS due_date
INNER JOIN ( FROM milestones
SELECT MIN(milestones.start_date) AS start_date, MAX(milestones.due_date) AS due_date INNER JOIN issues ON issues.milestone_id = milestones.id
FROM milestones INNER JOIN epic_issues ON epic_issues.issue_id = issues.id
INNER JOIN issues ON issues.milestone_id = milestones.id WHERE epic_issues.epic_id = #{epic_id}
INNER JOIN epic_issues ON epic_issues.issue_id = issues.id ) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date)
WHERE epic_issues.epic_id = #{epic_id} SQL
) inner_results ON (inner_results.start_date = milestones.start_date OR inner_results.due_date = milestones.due_date) ).pluck(*FIELDS)
WHERE epic_issues.epic_id = #{epic_id}
SQL
new(ActiveRecord::Base.connection.select_all(sql).to_a) new(results)
end end
def initialize(results) def initialize(results)
...@@ -25,19 +28,19 @@ module Epics ...@@ -25,19 +28,19 @@ module Epics
end end
def start_date def start_date
cast_as_date(start_date_sourcing_milestone&.fetch('start_date', nil)) start_date_sourcing_milestone&.slice(START_DATE_INDEX)
end end
def start_date_sourcing_milestone_id def start_date_sourcing_milestone_id
cast_as_id(start_date_sourcing_milestone&.fetch('id', nil)) start_date_sourcing_milestone&.slice(ID_INDEX)
end end
def due_date def due_date
cast_as_date(due_date_sourcing_milestone&.fetch('due_date', nil)) due_date_sourcing_milestone&.slice(DUE_DATE_INDEX)
end end
def due_date_sourcing_milestone_id def due_date_sourcing_milestone_id
cast_as_id(due_date_sourcing_milestone&.fetch('id', nil)) due_date_sourcing_milestone&.slice(ID_INDEX)
end end
private private
...@@ -46,30 +49,14 @@ module Epics ...@@ -46,30 +49,14 @@ module Epics
def start_date_sourcing_milestone def start_date_sourcing_milestone
@start_date_sourcing_milestone ||= results @start_date_sourcing_milestone ||= results
.reject { |row| row['start_date'].nil? } .reject { |row| row[START_DATE_INDEX].nil? }
.min_by { |row| row['start_date'] } .min_by { |row| row[START_DATE_INDEX] }
end end
def due_date_sourcing_milestone def due_date_sourcing_milestone
@due_date_sourcing_milestone ||= results @due_date_sourcing_milestone ||= results
.reject { |row| row['due_date'].nil? } .reject { |row| row[DUE_DATE_INDEX].nil? }
.max_by { |row| row['due_date'] } .max_by { |row| row[DUE_DATE_INDEX] }
end
def cast_as_date(result)
if result
Date.strptime(result, '%Y-%m-%d')
else
result
end
end
def cast_as_id(result)
if result
result.to_i
else
result
end
end end
end end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment