Class: TomSelect

Inherits:
Object
  • Object
show all
Defined in:
app/models/tom_select.rb

Class Method Summary collapse

Class Method Details

.format_json_results(view, results, page = nil, per_page = nil, id_method = nil, text_method = nil) {|item| ... } ⇒ Hash

Formats query results for Tom Select dropdowns
Handles both flat arrays and option groups

Parameters:

  • view (ActionController::Base)

    The controller context (for Pagy request access)

  • results (Array, ActiveRecord::Relation)

    The results to format

  • page (Integer, nil) (defaults to: nil)

    Current page number (default: 1)

  • per_page (Integer, nil) (defaults to: nil)

    Items per page (default: 20)

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

    Method to call for ID (default: :id)

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

    Method to call for text (default: :selection_name)

Yields:

  • (item)

    Optional block to format each item

Returns:

  • (Hash)

    Formatted results with pagination: { results: [...], pagination: { more: Boolean } }



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/models/tom_select.rb', line 15

def self.format_json_results(view, results, page = nil, per_page = nil, id_method = nil, text_method = nil, &)
  page = page.presence&.to_i || 1
  per_page = per_page.presence&.to_i || 20

  # Use Pagy in the controller's context (provides request for URL generation)
  # Use instance_exec to pass arguments explicitly for proper :countless support
  pagy, paginated_results =
    if results.is_a?(Array)
      # For arrays, use Pagy's offset pagination
      view.instance_exec(results, page, per_page) { |r, p, pp| pagy(:offset, r, page: p, limit: pp) }
    else
      # For ActiveRecord relations, use countless pagination (no COUNT query needed for infinite scrolling)
      view.instance_exec(results, page, per_page) { |r, p, pp| pagy(:countless, r, page: p, limit: pp) }
    end

  # Check if there's a next page (for infinite scrolling)
  more = !pagy.next.nil?

  results_array = paginated_results.map do |e|
    if block_given?
      yield(e)
    else
      id_method ||= :id
      text_method ||= :selection_name
      { id: e.try(id_method) || e.to_s, text: normalize_text(e.try(text_method) || e.to_s) }
    end
  end
  { results: results_array.uniq, pagination: { more: more } }
end

.format_option_groups(option_groups, pagination = nil) ⇒ Hash

Formats option groups (like Activity::ResourceList) for Tom Select
Option groups are already in the format: { text: "Group Name", children: [{ id, text }, ...] }
This ensures text fields are normalized and returns the format Tom Select expects

Parameters:

  • option_groups (Array<Hash>)

    Array of option groups with text and children

  • pagination (Hash, nil) (defaults to: nil)

    Pagination info: { more: Boolean }

Returns:

  • (Hash)

    Formatted results: { results: [...], pagination: { more: Boolean } }



67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'app/models/tom_select.rb', line 67

def self.format_option_groups(option_groups, pagination = nil)
  normalized_groups = option_groups.map do |group|
    {
      text: normalize_text(group[:text] || group['text'] || ''),
      children: (group[:children] || group['children'] || []).map do |child|
        {
          id: child[:id] || child['id'],
          text: normalize_text(child[:text] || child['text'] || '')
        }
      end
    }
  end

  {
    results: normalized_groups,
    pagination: pagination || { more: false }
  }
end

.normalize_text(text) ⇒ String

Normalizes text to always be a string (handles arrays, nil, etc.)

Parameters:

  • text (String, Array, nil)

    The text to normalize

Returns:

  • (String)

    Normalized text string



49
50
51
52
53
54
55
56
57
58
# File 'app/models/tom_select.rb', line 49

def self.normalize_text(text)
  case text
  when Array
    text.compact.join(' - ')
  when nil
    ''
  else
    text.to_s
  end
end