Class: Spree::SearchProvider::MetafieldSchema
- Inherits:
-
Object
- Object
- Spree::SearchProvider::MetafieldSchema
- Defined in:
- app/services/spree/search_provider/metafield_schema.rb
Overview
Product metafield definitions that participate in search/sort.
Constant Summary collapse
- TEXT_FILTER_PREDICATES =
Ransack-style predicates accepted per field type. Mirrors the operator sets the admin dashboard's filter panel offers for string/number columns (see packages/dashboard-core/src/components/table-toolbar.tsx).
%w[i_cont cont eq not_eq start end present blank].freeze
- NUMBER_FILTER_PREDICATES =
%w[eq gt gteq lt lteq present blank].freeze
- ORDERED_FILTER_PREDICATES =
Longest first so a key ending in
_i_contisn't mis-split as the shorter_contagainst a definition keyed..._i. (TEXT_FILTER_PREDICATES | NUMBER_FILTER_PREDICATES). sort_by { |predicate| -predicate.length }.freeze
Instance Method Summary collapse
- #entries ⇒ Hash{String => Spree::MetafieldDefinition}
- #entry_for(attribute_key) ⇒ Spree::MetafieldDefinition?
- #filter_predicates_for(field_type) ⇒ Array<String>
-
#filterable_attribute_keys ⇒ Array<String>
Every schema attribute accepts filters — values are already indexed for search/sort, so filtering rides on the same document keys.
-
#parse_filter(key) ⇒ Hash?
Splits a Ransack-style predicate key (e.g.
cf_custom_label_i_cont) into the definition it targets and the predicate. -
#parse_sort(sort) ⇒ Hash?
{ attribute:, direction: 'asc'|'desc' }.
-
#schema_version ⇒ String
Stamp for Store API filters cache keys.
- #searchable_attribute_keys ⇒ Array<String>
- #sort_ids ⇒ Array<String>
-
#sort_options ⇒ Array<Hash>
{ id:, label: }. - #sortable_attribute_keys ⇒ Array<String>
Instance Method Details
#entries ⇒ Hash{String => Spree::MetafieldDefinition}
19 20 21 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 19 def entries @entries ||= product_definitions.index_by(&:filter_key) end |
#entry_for(attribute_key) ⇒ Spree::MetafieldDefinition?
39 40 41 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 39 def entry_for(attribute_key) entries[attribute_key.to_s] end |
#filter_predicates_for(field_type) ⇒ Array<String>
112 113 114 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 112 def filter_predicates_for(field_type) field_type == 'number' ? NUMBER_FILTER_PREDICATES : TEXT_FILTER_PREDICATES end |
#filterable_attribute_keys ⇒ Array<String>
Every schema attribute accepts filters — values are already indexed for search/sort, so filtering rides on the same document keys.
47 48 49 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 47 def filterable_attribute_keys @filterable_attribute_keys ||= entries.keys end |
#parse_filter(key) ⇒ Hash?
Splits a Ransack-style predicate key (e.g. cf_custom_label_i_cont)
into the definition it targets and the predicate. Both search keys and
predicates contain underscores, so predicates are tried longest-first —
otherwise cf_x_i_cont would resolve as key x_i with predicate
cont. A key that itself ends in a predicate name (+..._eq_eq+) is
only reachable if the shorter split names a real definition.
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 94 def parse_filter(key) value = key.to_s return unless value.start_with?('cf_') ORDERED_FILTER_PREDICATES.each do |predicate| next unless value.end_with?("_#{predicate}") definition = entries[value.delete_suffix("_#{predicate}")] next unless definition && filter_predicates_for(definition.field_type).include?(predicate) return { definition: definition, predicate: predicate } end nil end |
#parse_sort(sort) ⇒ Hash?
Returns { attribute:, direction: 'asc'|'desc' }.
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 71 def parse_sort(sort) value = sort.to_s.strip return if value.blank? attribute = value.delete_prefix('-') definition = entry_for(attribute) return unless definition&.sortable? { attribute: attribute, direction: value.start_with?('-') ? 'desc' : 'asc' } end |
#schema_version ⇒ String
Stamp for Store API filters cache keys.
119 120 121 122 123 124 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 119 def schema_version @schema_version ||= [ entries.size, entries.each_value.filter_map(&:updated_at).max&.utc&.iso8601(6) ].join('-') end |
#searchable_attribute_keys ⇒ Array<String>
24 25 26 27 28 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 24 def searchable_attribute_keys @searchable_attribute_keys ||= entries.each_value.filter_map do |definition| definition.filter_key if definition.searchable? end end |
#sort_ids ⇒ Array<String>
52 53 54 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 52 def sort_ids @sort_ids ||= sortable_attribute_keys.flat_map { |key| [key, "-#{key}"] } end |
#sort_options ⇒ Array<Hash>
Returns { id:, label: }.
57 58 59 60 61 62 63 64 65 66 67 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 57 def @sort_options ||= entries.each_value.select(&:sortable?).flat_map do |definition| key = definition.filter_key name = definition.name.presence || key [ { id: key, label: sort_option_label(name, definition.field_type, :asc) }, { id: "-#{key}", label: sort_option_label(name, definition.field_type, :desc) } ] end end |
#sortable_attribute_keys ⇒ Array<String>
31 32 33 34 35 |
# File 'app/services/spree/search_provider/metafield_schema.rb', line 31 def sortable_attribute_keys @sortable_attribute_keys ||= entries.each_value.filter_map do |definition| definition.filter_key if definition.sortable? end end |