class OrderQuery::Column

An order column (sort column)

Attributes

custom_sql[R]
name[R]
order_enum[R]

Public Class Methods

new(scope, attr_name, *vals_and_or_dir, unique: nil, nulls: false, sql: nil) click to toggle source

@param scope [ActiveRecord::Relation] @param attr_name [Symbol] the name of the column, or the method providing

the value to sort by.

@param vals_and_or_dir [Array] optionally, values in the desired order,

and / or one of `:asc`, `:desc`. Default order is `:desc` if the values
are given (so the result is ordered like the values), `:asc` otherwise.

@param unique [Boolean] mark the attribute as unique to avoid redundant

columns. Default: `true` for primary key.

@param nulls [:first, :last, false] whether to consider NULLS to be

ordered first or last. If false, assumes that a column is not nullable
and raises [Errors::NonNullableColumnIsNullError] if a null is
encountered.

@param sql [String, nil] a custom sql fragment.

# File lib/order_query/column.rb, line 29
def initialize(scope, attr_name, *vals_and_or_dir,
               unique: nil, nulls: false, sql: nil)
  @name = attr_name
  @order_enum = vals_and_or_dir.shift if vals_and_or_dir[0].is_a?(Array)
  @direction = Direction.parse!(
    vals_and_or_dir.shift || (@order_enum ? :desc : :asc)
  )
  unless vals_and_or_dir.empty?
    fail ArgumentError,
         "extra arguments: #{vals_and_or_dir.map(&:inspect) * ', '}"
  end
  @unique = unique.nil? ? (name.to_s == scope.primary_key) : unique
  if @order_enum&.include?(nil)
    fail ArgumentError, '`nulls` cannot be set if a value is null' if nulls

    @nullable = true
    @nulls = if @order_enum[0].nil?
               @direction == :desc ? :first : :last
             else
               @direction == :desc ? :last : :first
             end
  else
    @nullable = !!nulls # rubocop:disable Style/DoubleNegation
    @nulls = NullsDirection.parse!(
      nulls || NullsDirection.default(scope, @direction)
    )
  end
  @custom_sql = sql
  @sql_builder = SQL::Column.new(scope, self)
end

Public Instance Methods

default_nulls_direction(reverse = false) click to toggle source

@return [:first, :last]

# File lib/order_query/column.rb, line 73
def default_nulls_direction(reverse = false)
  NullsDirection.default(scope, direction(reverse))
end
direction(reverse = false) click to toggle source

rubocop:enable Metrics/ParameterLists,Metrics/AbcSize rubocop:enable Metrics/CyclomaticComplexity,Metrics/PerceivedComplexity rubocop:enable Metrics/MethodLength

# File lib/order_query/column.rb, line 63
def direction(reverse = false)
  reverse ? Direction.reverse(@direction) : @direction
end
enum_side(value, side, strict = true) click to toggle source

@param [Object] value @param [:before, :after] side @return [Array] valid order values before / after the given value. @example for [:difficulty, [‘Easy’, ‘Normal’, ‘Hard’]]:

enum_side('Normal', :after) #=> ['Hard']
enum_side('Normal', :after, false) #=> ['Normal', 'Hard']
# File lib/order_query/column.rb, line 91
def enum_side(value, side, strict = true) # rubocop:disable Metrics/AbcSize
  ord = order_enum
  pos = ord.index(value)
  if pos
    dir = direction
    if side == :after && dir == :desc || side == :before && dir == :asc
      ord.from pos + (strict ? 1 : 0)
    else
      ord.first pos + (strict ? 0 : 1)
    end
  else
    # default to all if current is not in sort order values
    []
  end
end
inspect() click to toggle source
# File lib/order_query/column.rb, line 107
def inspect
  parts = [
    @name,
    (@order_enum.inspect if order_enum),
    ('unique' if @unique),
    (column_name if @custom_sql),
    @direction
  ].compact
  "(#{parts.join(' ')})"
end
nullable?() click to toggle source
# File lib/order_query/column.rb, line 77
def nullable?
  @nullable
end
nulls_direction(reverse = false) click to toggle source

@return [:first, :last]

# File lib/order_query/column.rb, line 68
def nulls_direction(reverse = false)
  reverse ? NullsDirection.reverse(@nulls) : @nulls
end
unique?() click to toggle source
# File lib/order_query/column.rb, line 81
def unique?
  @unique
end