Module: ProductLineUrls

Defined in:
app/constants/product_line_urls.rb

Overview

Stable lookup constants for product lines using slug_ltree paths.
These map to the slug_ltree column on the product_lines table —
an ltree built from the FriendlyId slug chain (e.g. "snow_melting.mat.powermat").

slug_ltree is unique per product line and supports fast ltree queries:
ProductLine.by_slug_ltree(path) — exact match
ProductLine.by_slug_ltree_descendants(path) — all descendants
ProductLine.by_slug_ltree_ancestors(path) — all ancestors

Usage in views:
<%= render Www::ProductCardsComponent.new(
product_line_slugs: [
ProductLineUrls::FLOOR_HEATING_TEMPZONE_FLEX_ROLL,
ProductLineUrls::FLOOR_HEATING_TEMPZONE_EASY_MAT
]
) %>

To verify all paths exist in database:
rails runner "ProductLineUrls.verify_all"

Constant Summary collapse

FLOOR_HEATING =

===========================================================================
Floor Heating - TempZone (tile/stone)

'floor_heating'
FLOOR_HEATING_TEMPZONE =
'floor_heating.tempzone'
FLOOR_HEATING_TEMPZONE_FLEX_ROLL =
'floor_heating.tempzone.flex_roll'
FLOOR_HEATING_TEMPZONE_EASY_MAT =
'floor_heating.tempzone.easy_mat'
FLOOR_HEATING_TEMPZONE_CABLE =
'floor_heating.tempzone.cable'
FLOOR_HEATING_TEMPZONE_RULER_CABLE =
'floor_heating.tempzone.ruler_cable'
FLOOR_HEATING_TEMPZONE_CUSTOM_MAT =
'floor_heating.tempzone.custom_mat'
FLOOR_HEATING_TEMPZONE_SHOWER_MAT_FLOOR =
'floor_heating.tempzone.shower_mat.floor'
FLOOR_HEATING_TEMPZONE_SHOWER_MAT_BENCH =
'floor_heating.tempzone.shower_mat.bench'
FLOOR_HEATING_TEMPZONE_INSTALLATION_KITS =
'floor_heating.tempzone.installation_kits'
FLOOR_HEATING_TEMPZONE_CABLE_KITS_UNCOUPLING_NTRUST2 =

TempZone Cable Kits

'floor_heating.tempzone.cable.kits_with_uncoupling_membrane.ntrust2'
FLOOR_HEATING_TEMPZONE_CABLE_KITS_UNCOUPLING_NJOY =
'floor_heating.tempzone.cable.kits_with_uncoupling_membrane.njoy'
FLOOR_HEATING_TEMPZONE_CABLE_KITS_FIXING_STRIPS_NTRUST2 =
'floor_heating.tempzone.cable.kits_with_fixing_strips.ntrust2'
FLOOR_HEATING_TEMPZONE_CABLE_KITS_FIXING_STRIPS_NJOY =
'floor_heating.tempzone.cable.kits_with_fixing_strips.njoy'
FLOOR_HEATING_TEMPZONE_FLEX_ROLL_TWIN_KITS_NTRUST2 =

TempZone Twin Conductor Kits

'floor_heating.tempzone.flex_roll.twin_conductor.kits.ntrust2'
FLOOR_HEATING_TEMPZONE_FLEX_ROLL_TWIN_KITS_NJOY =
'floor_heating.tempzone.flex_roll.twin_conductor.kits.njoy'
FLOOR_HEATING_TEMPZONE_EASY_MAT_TWIN_KITS_NTRUST2 =
'floor_heating.tempzone.easy_mat.twin_conductor.kits.ntrust2'
FLOOR_HEATING_TEMPZONE_EASY_MAT_TWIN_KITS_NJOY =
'floor_heating.tempzone.easy_mat.twin_conductor.kits.njoy'
FLOOR_HEATING_ENVIRON =

===========================================================================
Floor Heating - Environ (floating floors)

'floor_heating.environ'
FLOOR_HEATING_ENVIRON_FLEX_ROLL =
'floor_heating.environ.flex_roll'
FLOOR_HEATING_ENVIRON_EASY_MAT =
'floor_heating.environ.easy_mat'
FLOOR_HEATING_SLAB_HEAT =

===========================================================================
Floor Heating - Slab Heat (concrete)

'floor_heating.slab_heat'
FLOOR_HEATING_SLAB_HEAT_MAT =
'floor_heating.slab_heat.mat'
FLOOR_HEATING_SLAB_HEAT_CABLE =
'floor_heating.slab_heat.cable'
FLOOR_HEATING_UNDERLAYMENT =

===========================================================================
Floor Heating - Underlayment & Controls

'floor_heating.underlayment'
FLOOR_HEATING_UNDERLAYMENT_THERMALSHEET =
'floor_heating.underlayment.thermalsheet'
FLOOR_HEATING_UNDERLAYMENT_PRODESO =
'floor_heating.underlayment.prodeso'
FLOOR_HEATING_CONTROL =
'floor_heating.control'
SNOW_MELTING =

===========================================================================
Snow Melting

'snow_melting'
SNOW_MELTING_MAT =
'snow_melting.mat'
SNOW_MELTING_POWERMAT =
'snow_melting.mat.powermat'
SNOW_MELTING_OMNIMAT =
'snow_melting.mat.omnimat'
SNOW_MELTING_ECOMAT =
'snow_melting.mat.ecomat'
SNOW_MELTING_CABLE =
'snow_melting.cable'
SNOW_MELTING_CONTROL =
'snow_melting.control'
ROOF_GUTTER_DEICING =

===========================================================================
Roof & Gutter Deicing

'roof_and_gutter_deicing'
ROOF_GUTTER_DEICING_SELF_REGULATING =
'roof_and_gutter_deicing.self_regulating_cut_to_length_cable'
ROOF_GUTTER_DEICING_CONSTANT_WATTAGE =
'roof_and_gutter_deicing.constant_wattage.pre_assembled_plug_in_kits'
ROOF_GUTTER_DEICING_CONTROL =
'roof_and_gutter_deicing.self_regulating_cut_to_length_cable.control'
PIPE_FREEZE_PROTECTION =

===========================================================================
Pipe Freeze Protection

'pipe_freeze_protection'
PIPE_FREEZE_PROTECTION_SELF_REGULATING =
'pipe_freeze_protection.self_regulating_cable'
PIPE_FREEZE_PROTECTION_CONSTANT_WATTAGE =
'pipe_freeze_protection.constant_wattage_cable'
PIPE_FREEZE_PROTECTION_CONTROL =
'pipe_freeze_protection.self_regulating_cable.pipe_freeze_control'
TOWEL_WARMER =

===========================================================================
Towel Warmers

'towel_warmer'
TOWEL_WARMER_CLASSIC =
'towel_warmer.classic'
TOWEL_WARMER_COSMOPOLITAN =
'towel_warmer.cosmopolitan'
TOWEL_WARMER_CONTROL =
'towel_warmer.control'
TOWEL_WARMER_CRYSTAL_ACCESSORIES =
'towel_warmer.crystal_accessories'
RADIANT_PANEL =

===========================================================================
Radiant Panels

'radiant_panel'
RADIANT_PANEL_LAVA =
'radiant_panel.lava'
RADIANT_PANEL_EMBER =
'radiant_panel.ember'
RADIANT_PANEL_EMBER_GLASS =
'radiant_panel.ember.glass'
RADIANT_PANEL_EMBER_MIRROR =
'radiant_panel.ember.mirror'
RADIANT_PANEL_EMBER_FLEX =
'radiant_panel.ember.flex'
RADIANT_PANEL_CONTROL =
'radiant_panel.control'
LED_MIRROR =

===========================================================================
LED Mirrors & Defoggers

'led_mirror'
MIRROR_DEFOGGER =
'mirror_defogger'
COUNTERTOP_HEATER =

===========================================================================
Countertop Heaters

'countertop_heater'
COUNTERTOP_HEATER_STANDARD =
'countertop_heater.standard'
COUNTERTOP_HEATER_CONTROL =
'countertop_heater.control'
SERVICES_SMARTFIT =

===========================================================================
Services

'services.smartfit'
SERVICES_SMARTINSTALL =
'services.smartinstall'
SERVICES_SMARTFIX =
'services.smartfix'
SERVICES_SMARTGUIDE =
'services.smartguide'
FLOOR_HEATING_TEMPZONE_MATS =

TempZone mats & rolls (tile/stone)

[
  FLOOR_HEATING_TEMPZONE_FLEX_ROLL,
  FLOOR_HEATING_TEMPZONE_EASY_MAT,
  FLOOR_HEATING_TEMPZONE_CUSTOM_MAT
].freeze
FLOOR_HEATING_TEMPZONE_CABLES =

TempZone cables

[
  FLOOR_HEATING_TEMPZONE_CABLE,
  FLOOR_HEATING_TEMPZONE_RULER_CABLE
].freeze
FLOOR_HEATING_ENVIRON_PRODUCTS =

Environ products (floating floors)

[
  FLOOR_HEATING_ENVIRON_FLEX_ROLL,
  FLOOR_HEATING_ENVIRON_EASY_MAT
].freeze
FLOOR_HEATING_SLAB_HEAT_PRODUCTS =

Slab Heat products (concrete)

[
  FLOOR_HEATING_SLAB_HEAT_MAT,
  FLOOR_HEATING_SLAB_HEAT_CABLE
].freeze
FLOOR_HEATING_SHOWER_PRODUCTS =

Shower heating products

[
  FLOOR_HEATING_TEMPZONE_SHOWER_MAT_FLOOR,
  FLOOR_HEATING_TEMPZONE_SHOWER_MAT_BENCH
].freeze
FLOOR_HEATING_PRODUCTS =

All floor heating product options (for landing pages)

[
  FLOOR_HEATING_TEMPZONE_FLEX_ROLL,
  FLOOR_HEATING_TEMPZONE_EASY_MAT,
  FLOOR_HEATING_TEMPZONE_CABLE,
  FLOOR_HEATING_TEMPZONE_CUSTOM_MAT,
  FLOOR_HEATING_ENVIRON_FLEX_ROLL,
  FLOOR_HEATING_ENVIRON_EASY_MAT,
  FLOOR_HEATING_SLAB_HEAT_MAT,
  FLOOR_HEATING_SLAB_HEAT_CABLE
].freeze
SNOW_MELTING_PRODUCTS =

Snow melting products (using individual mat types instead of parent)
Note: EcoMat excluded - special order only, not publicly available

[
  SNOW_MELTING_POWERMAT,
  SNOW_MELTING_OMNIMAT,
  SNOW_MELTING_CABLE
].freeze
ROOF_GUTTER_DEICING_PRODUCTS =

Roof & gutter deicing products

[
  ROOF_GUTTER_DEICING_SELF_REGULATING,
  ROOF_GUTTER_DEICING_CONSTANT_WATTAGE
].freeze
PIPE_FREEZE_PROTECTION_PRODUCTS =

Pipe freeze protection products

[
  PIPE_FREEZE_PROTECTION_SELF_REGULATING,
  PIPE_FREEZE_PROTECTION_CONSTANT_WATTAGE
].freeze
RADIANT_PANEL_EMBER_PRODUCTS =

Radiant panel ember products

[
  RADIANT_PANEL_EMBER_GLASS,
  RADIANT_PANEL_EMBER_MIRROR,
  RADIANT_PANEL_EMBER_FLEX
].freeze
ALL_CONTROLS =

All control product lines

[
  FLOOR_HEATING_CONTROL,
  SNOW_MELTING_CONTROL,
  ROOF_GUTTER_DEICING_CONTROL,
  PIPE_FREEZE_PROTECTION_CONTROL,
  RADIANT_PANEL_CONTROL,
  TOWEL_WARMER_CONTROL,
  COUNTERTOP_HEATER_CONTROL
].freeze

Class Method Summary collapse

Class Method Details

.all_pathsObject

===========================================================================
Verification



229
230
231
232
233
# File 'app/constants/product_line_urls.rb', line 229

def self.all_paths
  constants.map { |c| const_get(c) }
           .select { |v| v.is_a?(String) }
           .uniq
end

.suggest_missingObject



259
260
261
262
263
264
265
266
267
268
269
270
# File 'app/constants/product_line_urls.rb', line 259

def self.suggest_missing
  existing = all_paths.to_set
  db_paths = ProductLine.where.not(inactive: true).pluck(:slug_ltree).compact.map(&:to_s)

  missing = db_paths - existing.to_a
  if missing.empty?
    puts 'All active product line slug_ltree paths are defined as constants'
  else
    puts "#{missing.size} product line paths not yet defined as constants:"
    missing.sort.each { |p| puts "  #{p}" }
  end
end

.verify_allObject



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'app/constants/product_line_urls.rb', line 235

def self.verify_all
  errors = []
  found = 0

  all_paths.each do |path|
    pl = ProductLine.find_by(slug_ltree: path)
    if pl.nil?
      errors << "ProductLine with slug_ltree='#{path}' not found"
    else
      found += 1
    end
  end

  if errors.empty?
    puts "All #{found} product line paths verified!"
    true
  else
    puts "#{found} paths found"
    puts "#{errors.size} errors:"
    errors.each { |e| puts "  - #{e}" }
    false
  end
end