diff options
author | Douglas Barbosa Alexandre <dbalexandre@gmail.com> | 2018-10-19 13:41:40 +0000 |
---|---|---|
committer | Douglas Barbosa Alexandre <dbalexandre@gmail.com> | 2018-10-19 13:41:40 +0000 |
commit | 80cce65d7e77088c96305906e8c7637d303a3ce5 (patch) | |
tree | ffe948936ba0402fd51d1fc03a87b43258859238 /app | |
parent | ce6a21f742051271ae5e55795fead023f1a73068 (diff) | |
parent | c871faa3e42edf7c1d92669cf18a5b0de7c84ace (diff) | |
download | gitlab-ce-80cce65d7e77088c96305906e8c7637d303a3ce5.tar.gz |
Merge branch 'ccr/43034_issues_controller_100_queries' into 'master'
Add preload for routes and namespaces for issues controller.
Closes #43034
See merge request gitlab-org/gitlab-ce!21651
Diffstat (limited to 'app')
-rw-r--r-- | app/controllers/boards/issues_controller.rb | 17 | ||||
-rw-r--r-- | app/models/concerns/relative_positioning.rb | 79 | ||||
-rw-r--r-- | app/models/list.rb | 1 | ||||
-rw-r--r-- | app/services/boards/lists/list_service.rb | 2 |
4 files changed, 58 insertions, 41 deletions
diff --git a/app/controllers/boards/issues_controller.rb b/app/controllers/boards/issues_controller.rb index 4f3d737e3ce..7f874687212 100644 --- a/app/controllers/boards/issues_controller.rb +++ b/app/controllers/boards/issues_controller.rb @@ -18,10 +18,15 @@ module Boards list_service = Boards::Issues::ListService.new(board_parent, current_user, filter_params) issues = list_service.execute issues = issues.page(params[:page]).per(params[:per] || 20).without_count - make_sure_position_is_set(issues) if Gitlab::Database.read_write? - issues = issues.preload(:project, - :milestone, + Issue.move_to_end(issues) if Gitlab::Database.read_write? + issues = issues.preload(:milestone, :assignees, + project: [ + :route, + { + namespace: [:route] + } + ], labels: [:priorities], notes: [:award_emoji, :author] ) @@ -60,12 +65,6 @@ module Boards render json: data end - def make_sure_position_is_set(issues) - issues.each do |issue| - issue.move_to_end && issue.save unless issue.relative_position - end - end - def issue @issue ||= issues_finder.find(params[:id]) end diff --git a/app/models/concerns/relative_positioning.rb b/app/models/concerns/relative_positioning.rb index 85229cded5d..045bf392ac8 100644 --- a/app/models/concerns/relative_positioning.rb +++ b/app/models/concerns/relative_positioning.rb @@ -12,6 +12,49 @@ module RelativePositioning after_save :save_positionable_neighbours end + class_methods do + def move_to_end(objects) + parent_ids = objects.map(&:parent_ids).flatten.uniq + max_relative_position = in_parents(parent_ids).maximum(:relative_position) || START_POSITION + objects = objects.reject(&:relative_position) + + self.transaction do + objects.each do |object| + relative_position = position_between(max_relative_position, MAX_POSITION) + object.relative_position = relative_position + max_relative_position = relative_position + object.save + end + end + end + + # This method takes two integer values (positions) and + # calculates the position between them. The range is huge as + # the maximum integer value is 2147483647. We are incrementing position by IDEAL_DISTANCE * 2 every time + # when we have enough space. If distance is less then IDEAL_DISTANCE we are calculating an average number + def position_between(pos_before, pos_after) + pos_before ||= MIN_POSITION + pos_after ||= MAX_POSITION + + pos_before, pos_after = [pos_before, pos_after].sort + + halfway = (pos_after + pos_before) / 2 + distance_to_halfway = pos_after - halfway + + if distance_to_halfway < IDEAL_DISTANCE + halfway + else + if pos_before == MIN_POSITION + pos_after - IDEAL_DISTANCE + elsif pos_after == MAX_POSITION + pos_before + IDEAL_DISTANCE + else + halfway + end + end + end + end + def min_relative_position self.class.in_parents(parent_ids).minimum(:relative_position) end @@ -57,7 +100,7 @@ module RelativePositioning @positionable_neighbours = [before] # rubocop:disable Gitlab/ModuleWithInstanceVariables end - self.relative_position = position_between(before.relative_position, after.relative_position) + self.relative_position = self.class.position_between(before.relative_position, after.relative_position) end def move_after(before = self) @@ -72,7 +115,7 @@ module RelativePositioning pos_after = issue_to_move.relative_position end - self.relative_position = position_between(pos_before, pos_after) + self.relative_position = self.class.position_between(pos_before, pos_after) end def move_before(after = self) @@ -87,15 +130,15 @@ module RelativePositioning pos_before = issue_to_move.relative_position end - self.relative_position = position_between(pos_before, pos_after) + self.relative_position = self.class.position_between(pos_before, pos_after) end def move_to_end - self.relative_position = position_between(max_relative_position || START_POSITION, MAX_POSITION) + self.relative_position = self.class.position_between(max_relative_position || START_POSITION, MAX_POSITION) end def move_to_start - self.relative_position = position_between(min_relative_position || START_POSITION, MIN_POSITION) + self.relative_position = self.class.position_between(min_relative_position || START_POSITION, MIN_POSITION) end # Indicates if there is an issue that should be shifted to free the place @@ -112,32 +155,6 @@ module RelativePositioning private - # This method takes two integer values (positions) and - # calculates the position between them. The range is huge as - # the maximum integer value is 2147483647. We are incrementing position by IDEAL_DISTANCE * 2 every time - # when we have enough space. If distance is less then IDEAL_DISTANCE we are calculating an average number - def position_between(pos_before, pos_after) - pos_before ||= MIN_POSITION - pos_after ||= MAX_POSITION - - pos_before, pos_after = [pos_before, pos_after].sort - - halfway = (pos_after + pos_before) / 2 - distance_to_halfway = pos_after - halfway - - if distance_to_halfway < IDEAL_DISTANCE - halfway - else - if pos_before == MIN_POSITION - pos_after - IDEAL_DISTANCE - elsif pos_after == MAX_POSITION - pos_before + IDEAL_DISTANCE - else - halfway - end - end - end - # rubocop:disable Gitlab/ModuleWithInstanceVariables def save_positionable_neighbours return unless @positionable_neighbours diff --git a/app/models/list.rb b/app/models/list.rb index 1a30acc83cf..029685be927 100644 --- a/app/models/list.rb +++ b/app/models/list.rb @@ -15,6 +15,7 @@ class List < ActiveRecord::Base scope :destroyable, -> { where(list_type: list_types.slice(*destroyable_types).values) } scope :movable, -> { where(list_type: list_types.slice(*movable_types).values) } + scope :preload_associations, -> { preload(:board, :label) } class << self def destroyable_types diff --git a/app/services/boards/lists/list_service.rb b/app/services/boards/lists/list_service.rb index e10eb52e041..5cf5f14a55b 100644 --- a/app/services/boards/lists/list_service.rb +++ b/app/services/boards/lists/list_service.rb @@ -6,7 +6,7 @@ module Boards def execute(board) board.lists.create(list_type: :backlog) unless board.lists.backlog.exists? - board.lists + board.lists.preload_associations end end end |