Class: ParamsReady::Ordering::OrderingParameterDefinition

Inherits:
Parameter::ArrayParameterDefinition show all
Defined in:
lib/params_ready/ordering/ordering.rb

Constant Summary collapse

COLUMN_DELIMITER =
'|'
FIELD_DELIMITER =
'-'

Instance Attribute Summary collapse

Attributes inherited from Parameter::Definition

#default

Attributes inherited from Parameter::AbstractDefinition

#altn, #name

Instance Method Summary collapse

Methods inherited from Parameter::ArrayParameterDefinition

#ensure_canonical

Methods included from Parameter::ArrayParameterDefinition::ArrayLike

#duplicate_value, #freeze_value

Methods inherited from Parameter::Definition

#canonical_default, #default_defined?, #fetch_callable_default, #fetch_default, #memoize?, #name_for_formatter, #no_input?, #no_output?, #postprocess, #preprocess, #restricted_for_format?, #set_local, #set_no_input, #set_postprocessor, #set_preprocessor

Methods inherited from Parameter::AbstractDefinition

#create, #from_hash, #from_input, #normalize_alternative_name, #parameter_class

Methods included from Extensions::Freezer

#freeze_variable, #freeze_variables, #variables_to_freeze

Methods included from Extensions::Finalizer

#obligatory, #obligatory!

Methods included from Extensions::ClassReaderWriter

#class_reader_writer

Methods included from Extensions::LateInit

#late_init

Methods included from Extensions::Collection

#collection

Methods included from Extensions::Freezer::InstanceMethods

#freeze

Constructor Details

#initialize(columns, default = Extensions::Undefined) ⇒ OrderingParameterDefinition

Returns a new instance of OrderingParameterDefinition.

Raises:



160
161
162
163
164
165
166
167
168
169
# File 'lib/params_ready/ordering/ordering.rb', line 160

def initialize(columns, default = Extensions::Undefined)
  invalid = columns.values.uniq.reject do |column|
    column.is_a? Column
  end
  raise ParamsReadyError, "Invalid ordering values: #{invalid.join(", ")}" unless invalid.length == 0
  @columns = columns.transform_keys { |k| k.to_sym }
  @required_columns = nil
  @primary_keys = Set.new
  super :ordering, altn: :ord, prototype: nil, default: default
end

Instance Attribute Details

#columnsObject (readonly)

Returns the value of attribute columns.



156
157
158
# File 'lib/params_ready/ordering/ordering.rb', line 156

def columns
  @columns
end

#primary_keysObject (readonly)

Returns the value of attribute primary_keys.



156
157
158
# File 'lib/params_ready/ordering/ordering.rb', line 156

def primary_keys
  @primary_keys
end

Instance Method Details

#add_column(name, ordering, expression:, arel_table:, nulls: :default, required: false, pk: false) ⇒ Object

Raises:



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/params_ready/ordering/ordering.rb', line 195

def add_column(
  name,
  ordering,
  expression:,
  arel_table:,
  nulls: :default,
  required: false,
  pk: false
)
  raise ParamsReadyError, "Column name taken: #{name}" if @columns.key? name
  raise ParamsReadyError, "Can't add column after default defined" unless @default == Extensions::Undefined
  @primary_keys << name if pk == true

  column = Column.new(
    ordering,
    expression: expression,
    arel_table: arel_table,
    nulls: nulls,
    required: required,
    pk: pk
  )
  @columns[name] = column
end

#create_prototype(columns) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
# File 'lib/params_ready/ordering/ordering.rb', line 219

def create_prototype(columns)
  Builder.define_tuple(:column) do
    marshal using: :string, separator: FIELD_DELIMITER
    field :symbol, :column_name do
      constrain Value::EnumConstraint.new(columns.keys)
    end
    field :symbol, :column_ordering do
      constrain Value::EnumConstraint.new(Column::DIRECTIONS)
    end
  end
end

#finishObject

Raises:



266
267
268
269
270
271
# File 'lib/params_ready/ordering/ordering.rb', line 266

def finish
  raise ParamsReadyError, "No ordering column defined" if @columns.empty?
  set_required_columns
  set_default([]) unless default_defined?
  super
end

#required?(name = nil) ⇒ Boolean

Returns:

  • (Boolean)


189
190
191
192
193
# File 'lib/params_ready/ordering/ordering.rb', line 189

def required?(name = nil)
  return !@required_columns.empty? if name.nil?

  @required_columns.member?(name)
end

#set_default(value) ⇒ Object

Raises:



171
172
173
174
175
176
177
# File 'lib/params_ready/ordering/ordering.rb', line 171

def set_default(value)
  raise ParamsReadyError, "Prototype for ordering expected to be nil" unless @prototype.nil?
  set_required_columns

  @prototype = create_prototype columns
  super value
end

#set_required_columnsObject



179
180
181
182
183
184
185
186
187
# File 'lib/params_ready/ordering/ordering.rb', line 179

def set_required_columns
  return unless @required_columns.nil?

  @required_columns = @columns.select do |_name, value|
    value.required
  end.map do |name, _value|
    name
  end
end

#try_canonicalize(input, context, validator = nil, freeze: false) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/params_ready/ordering/ordering.rb', line 231

def try_canonicalize(input, context, validator = nil, freeze: false)
  input ||= [%w(none none)]
  canonical, validator = case input
  when String
    raise ParamsReadyError, "Freeze option expected to be false" if freeze
    array = input.split(COLUMN_DELIMITER)
    try_canonicalize(array, context, validator, freeze: false)
  when Array
    super
  else
    raise ParamsReadyError, "Unexpected type for #{name}: #{input.class.name}"
  end
  unique_columns = unique_columns(canonical)
  with_required = with_required(unique_columns)
  [with_required.values, validator]
end

#unique_columns(array) ⇒ Object



248
249
250
251
252
253
254
255
# File 'lib/params_ready/ordering/ordering.rb', line 248

def unique_columns(array)
  array.each_with_object({}) do |column, hash|
    name = column.first.unwrap
    next if hash.key? name

    hash[name] = column
  end
end

#with_required(hash) ⇒ Object



257
258
259
260
261
262
263
264
# File 'lib/params_ready/ordering/ordering.rb', line 257

def with_required(hash)
  @required_columns.each_with_object(hash) do |name, result|
    next if result.key? name
    column = @columns[name]
    _, tuple = @prototype.from_input([name, column.ordering])
    hash[name] = tuple
  end
end