Module: CoreExtensions::ActiveRecord::Sort

Defined in:
lib/core_extensions/active_record/sort.rb

Overview

Assumes that the model has the #position attribute and adds 2 features to a model that includes it:

  1. Set the :position to the next highest value when a new row is added. If the model has a position_sorting_scope scope or class method, this is used to narrow the range of records searched when finding the current max position

  2. Add ability to sort rows based on an array of ids.

TODO: move to a model concern and include selectively rather than globally.

Defined Under Namespace

Modules: ClassMethods

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



14
15
16
17
18
# File 'lib/core_extensions/active_record/sort.rb', line 14

def self.included(base)
  base.extend ClassMethods

  base.before_create :set_position
end

Instance Method Details

#set_positionObject

Invoked by the callback when a record is created to set the initial value of #position. If no position_sorting_scope is defined on the model class, we set position to the max position in the whole table. If position_sorting_scope is provided we use it to refine the grouping and hence the max(position) found - for example to get the max position where patient_id = 123

Example scope in a model:

scope :position_sorting_scope, ->(problem) { where(patient_id: problem.patient.id) }


40
41
42
43
44
45
46
47
48
49
# File 'lib/core_extensions/active_record/sort.rb', line 40

def set_position
  return unless respond_to?(:position)

  scope = if self.class.respond_to?(:position_sorting_scope)
            self.class.position_sorting_scope(self)
          else
            self.class
          end
  self.position = (scope.maximum(:position) || 0) + 1
end