diff options
author | Chantal Rollison <crollison@gitlab.com> | 2018-09-10 10:26:33 -0700 |
---|---|---|
committer | Chantal Rollison <crollison@gitlab.com> | 2018-10-18 18:43:50 -0700 |
commit | c871faa3e42edf7c1d92669cf18a5b0de7c84ace (patch) | |
tree | 2444e8fa9d9233ff245e93076b610a47022146b9 /app/models/concerns/relative_positioning.rb | |
parent | a88004c876b94d44ce61c19d8c4c42e8de636f58 (diff) | |
download | gitlab-ce-c871faa3e42edf7c1d92669cf18a5b0de7c84ace.tar.gz |
Add preload in issues controller
Diffstat (limited to 'app/models/concerns/relative_positioning.rb')
-rw-r--r-- | app/models/concerns/relative_positioning.rb | 79 |
1 files changed, 48 insertions, 31 deletions
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 |