Class: Autoselect::Level

Inherits:
Object
  • Object
show all
Defined in:
lib/autoselect/level.rb

Overview

lib/autoselect/level.rb

Base class for all autoselect levels. Each level is a named, independent search strategy. Levels do not fork; they are executed sequentially by the Autoselect base class when their predecessor returns empty results (the fuse mechanic).

Rendering responsibility:

Internal levels use the default record_* methods, which delegate to
per-model helpers in app/helpers/ (e.g. taxon_name_autoselect_tag).
External levels override record_* directly — they must not rely on the
helper pattern because their records are POJOs, not AR instances.

Constant Summary collapse

DEFAULT_FUSE_MS =
600
EXTERNAL_FUSE_MS =
2000
MINIMUM_RESULTS =

escalate when result count < this value

1

Instance Method Summary collapse

Instance Method Details

#call(term:, operator: nil, project_id: nil, user_id: nil, **kwargs) ⇒ Array

Execute the level search.

Parameters:

  • term (String)

    the effective search term (operators stripped)

  • operator (Symbol, nil) (defaults to: nil)

    parsed operator if any

  • project_id (Integer, nil) (defaults to: nil)
  • user_id (Integer, nil) (defaults to: nil)
  • kwargs (Hash)

    level-specific params

Returns:

  • (Array)

    of model instances (ActiveRecord records or POJOs)

Raises:

  • (NotImplementedError)


57
58
59
# File 'lib/autoselect/level.rb', line 57

def call(term:, operator: nil, project_id: nil, user_id: nil, **kwargs)
  raise NotImplementedError, "#{self.class} must implement #call"
end

#descriptionString

Returns description shown in help overlay.

Returns:

  • (String)

    description shown in help overlay

Raises:

  • (NotImplementedError)


31
32
33
# File 'lib/autoselect/level.rb', line 31

def description
  raise NotImplementedError, "#{self.class} must implement #description"
end

#external?Boolean

Returns true when this level calls outside the database.

Returns:

  • (Boolean)

    true when this level calls outside the database



36
37
38
# File 'lib/autoselect/level.rb', line 36

def external?
  false
end

#fuse_msInteger

Returns milliseconds for the fuse animation before auto-escalating.

Returns:

  • (Integer)

    milliseconds for the fuse animation before auto-escalating



41
42
43
# File 'lib/autoselect/level.rb', line 41

def fuse_ms
  external? ? EXTERNAL_FUSE_MS : DEFAULT_FUSE_MS
end

#keySymbol

Returns unique identifier for this level, e.g. :fast, :smart.

Returns:

  • (Symbol)

    unique identifier for this level, e.g. :fast, :smart

Raises:

  • (NotImplementedError)


21
22
23
# File 'lib/autoselect/level.rb', line 21

def key
  raise NotImplementedError, "#{self.class} must implement #key"
end

#labelString

Returns human-readable label.

Returns:

  • (String)

    human-readable label

Raises:

  • (NotImplementedError)


26
27
28
# File 'lib/autoselect/level.rb', line 26

def label
  raise NotImplementedError, "#{self.class} must implement #label"
end

#metadataHash

Returns the metadata representation included in config responses.

Returns:

  • (Hash)

    the metadata representation included in config responses



62
63
64
65
66
67
68
69
70
# File 'lib/autoselect/level.rb', line 62

def 
  {
    key: key.to_s,
    label:,
    description:,
    external: external?,
    fuse_ms:
  }
end

#minimum_resultsInteger

Returns minimum results to suppress escalation.

Returns:

  • (Integer)

    minimum results to suppress escalation



46
47
48
# File 'lib/autoselect/level.rb', line 46

def minimum_results
  MINIMUM_RESULTS
end

#model_keyObject (private)

Derives the snake_case model name from the level's class namespace. Autoselect::TaxonName::Levels::Fast → 'taxon_name'



111
112
113
# File 'lib/autoselect/level.rb', line 111

def model_key
  self.class.name.split('::')[-3].underscore
end

#record_info(record) ⇒ Object

Array of disambiguation strings shown right-justified in the dropdown row. Delegates to _autoselect_info in app/helpers by default. External levels must override this.



95
96
97
98
99
100
# File 'lib/autoselect/level.rb', line 95

def record_info(record)
  h = ApplicationController.helpers
  helper = "#{model_key}_autoselect_info"
  return h.send(helper, record) if h.respond_to?(helper)
  []
end

#record_info_html(record) ⇒ Object

HTML string joining record_info with  



103
104
105
# File 'lib/autoselect/level.rb', line 103

def record_info_html(record)
  record_info(record).compact.join('&nbsp;')
end

#record_label(record) ⇒ Object

Plain-text label shown in the input after selection (no HTML). Delegates to label_for_ in app/helpers by default. External levels must override this.



75
76
77
78
79
80
# File 'lib/autoselect/level.rb', line 75

def record_label(record)
  h = ApplicationController.helpers
  helper = "label_for_#{model_key}"
  return h.send(helper, record).to_s if h.respond_to?(helper)
  record.to_s
end

#record_label_html(record) ⇒ Object

HTML label shown left-justified in the dropdown row. Delegates to _autoselect_tag in app/helpers by default. External levels must override this.



85
86
87
88
89
90
# File 'lib/autoselect/level.rb', line 85

def record_label_html(record)
  h = ApplicationController.helpers
  helper = "#{model_key}_autoselect_tag"
  return h.send(helper, record).to_s if h.respond_to?(helper)
  record_label(record)
end