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)


73
74
75
# File 'lib/autoselect/level.rb', line 73

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

#description ⇒ String

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_ms ⇒ Integer

Returns milliseconds for the fuse animation before auto-escalating.

Returns:

  • (Integer) —

    milliseconds for the fuse animation before auto-escalating



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

def fuse_ms
  external? ? EXTERNAL_FUSE_MS : DEFAULT_FUSE_MS
end

#is_default ⇒ Boolean

Returns whether this level should be checked (visible in the fuse bar) by default, absent any stored user preference. Task-specific/niche levels (e.g. a level only ever included when explicitly requested by a particular caller) should override this to false so they stay opt-in.

Returns:

  • (Boolean) —

    whether this level should be checked (visible in the fuse bar) by default, absent any stored user preference. Task-specific/niche levels (e.g. a level only ever included when explicitly requested by a particular caller) should override this to false so they stay opt-in.



44
45
46
# File 'lib/autoselect/level.rb', line 44

def is_default
  true
end

#key ⇒ Symbol

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

#label ⇒ String

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

#metadata ⇒ Hash

Returns the metadata representation included in config responses.

Returns:

  • (Hash) —

    the metadata representation included in config responses



78
79
80
81
82
83
84
85
86
87
88
# File 'lib/autoselect/level.rb', line 78

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

#minimum_results ⇒ Integer

Returns minimum results to suppress escalation.

Returns:

  • (Integer) —

    minimum results to suppress escalation



62
63
64
# File 'lib/autoselect/level.rb', line 62

def minimum_results
  MINIMUM_RESULTS
end

#model_key ⇒ Object (private)

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



129
130
131
# File 'lib/autoselect/level.rb', line 129

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

#options_level ⇒ Symbol?

Returns the key of another level whose stored preference options this level searches with, instead of its own. For levels that share one setting (e.g. every Catalogue of Life level uses the same dataset) so it's stored, and set, in one place.

Returns:

  • (Symbol, nil) —

    the key of another level whose stored preference options this level searches with, instead of its own. For levels that share one setting (e.g. every Catalogue of Life level uses the same dataset) so it's stored, and set, in one place.



52
53
54
# File 'lib/autoselect/level.rb', line 52

def options_level
  nil
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.



113
114
115
116
117
118
# File 'lib/autoselect/level.rb', line 113

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  



121
122
123
# File 'lib/autoselect/level.rb', line 121

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.



93
94
95
96
97
98
# File 'lib/autoselect/level.rb', line 93

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, term = nil) ⇒ Object

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



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

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