Module: LtreePaths
- Defined in:
- app/constants/ltree_paths.rb
Overview
Hardcoded ltree paths for common product categories and product lines.
These eliminate the need for database lookups when filtering by known hierarchies.
IMPORTANT: These use SLUG-BASED paths (e.g., 'floor_heating.tempzone') NOT ID-based paths.
Slug paths are more readable and stable than IDs which can change if records are deleted/recreated.
Usage in scopes:
where('pc_path_slugs <@ ?', LtreePaths::PC_GOODS)
where('primary_pl_path_slugs <@ ?', LtreePaths::PL_FLOOR_HEATING)
For Item queries, use the slug columns on items table:
Item.where('pc_path_slugs <@ ?', LtreePaths::PC_HEATING_ELEMENTS)
IMPORTANT: If the hierarchy structure changes (parent reassignment or rename), these paths
must be updated. Run rails runner "LtreePaths.verify_all" to check validity.
Constant Summary collapse
- PC_GOODS =
===========================================================================
Product Category paths (use pc_path_slugs column)
Format: category_name.subcategory_name (underscored slugs) 'goods'- PC_SERVICES =
Pc services.
'services'- PC_SHIPPING =
Pc shipping.
'shipping'- PC_SHIPPING_AND_HANDLING =
Pc shipping and handling.
'shipping_and_handling'- PC_HEATING_ELEMENTS =
Pc heating elements.
'goods.heating_elements'- PC_HEATING_ELEMENTS_HEATING_CABLES =
Pc heating elements heating cables.
'goods.heating_elements.heating_cables'- PC_HEATING_ELEMENTS_CUSTOM_MATS =
Pc heating elements custom mats.
'goods.heating_elements.heating_custom_mats'- PC_HEATING_ELEMENTS_COUNTERTOP =
Pc heating elements countertop.
'goods.heating_elements.countertop_heaters'- PC_CONTROLS =
Pc controls.
'goods.controls'- PC_CONTROLS_THERMOSTATS =
Pc controls thermostats.
'goods.controls.thermostats'- PC_ACCESSORIES =
Pc accessories.
'goods.accessories'- PC_ACCESSORIES_INSULATIONS =
Pc accessories insulations.
'goods.accessories.insulations'- PC_ACCESSORIES_MEMBRANES =
Pc accessories membranes.
'goods.accessories.membranes'- PC_SPARE_PARTS =
Pc spare parts.
'goods.spare_parts'- PC_SPARE_PARTS_COLD_LEADS =
Pc spare parts cold leads.
'goods.spare_parts.cold_leads'- PC_TOOLS =
Pc tools.
'goods.tools'- PC_POWER =
Pc power.
'goods.power'- PC_POWER_RELAY_PANELS =
Pc power relay panels.
'goods.power.relay_panels'- PC_POWER_MODULES =
Pc power modules.
'goods.power.modules'- PC_SENSORS =
Pc sensors.
'goods.sensors'- PC_TOWEL_WARMERS =
Pc towel warmers.
'goods.towel_warmers'- PC_TOWEL_WARMERS_PLUG_IN =
Pc towel warmers plug in.
'goods.towel_warmers.plug_in'- PC_TOWEL_WARMERS_HARDWIRED =
Pc towel warmers hardwired.
'goods.towel_warmers.hardwired'- PC_TOWEL_WARMERS_DUAL_CONNECTION =
Pc towel warmers dual connection.
'goods.towel_warmers.dual_connection'- PC_MIRROR_DEFOGGERS =
Pc mirror defoggers.
'goods.mirror_defoggers'- PC_MIRRORS =
Pc mirrors.
'goods.mirrors'- PC_INFRARED_HEATING_PANELS =
Pc infrared heating panels.
'goods.infrared_heating_panels'- PC_INFRARED_HEATING_PANELS_PLUG_IN =
Pc infrared heating panels plug in.
'goods.infrared_heating_panels.plug_in'- PC_INFRARED_HEATING_PANELS_HARDWIRED =
Pc infrared heating panels hardwired.
'goods.infrared_heating_panels.hardwired'- PC_UPGRADES =
Pc upgrades.
'goods.upgrades'- PC_PUBLICATIONS =
Pc publications.
'goods.publications'- PC_PUBLICATIONS_INSTALLATION =
Pc publications installation.
'goods.publications.installation'- PL_FLOOR_HEATING =
===========================================================================
Product Line paths (use primary_pl_path_slugs column)
Format: product_line_name.child_name (underscored slugs) 'floor_heating'- PL_FLOOR_HEATING_TEMPZONE =
Pl floor heating tempzone.
'floor_heating.tempzone'- PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL =
Pl floor heating tempzone flex roll.
'floor_heating.tempzone.flex_roll'- PL_FLOOR_HEATING_TEMPZONE_EASY_MAT =
Pl floor heating tempzone easy mat.
'floor_heating.tempzone.easy_mat'- PL_FLOOR_HEATING_TEMPZONE_CABLE =
Pl floor heating tempzone cable.
'floor_heating.tempzone.cable'- PL_FLOOR_HEATING_TEMPZONE_THIN_CABLE =
Pl floor heating tempzone thin cable.
'floor_heating.tempzone.thin_cable'- PL_FLOOR_HEATING_TEMPZONE_RULER_CABLE =
Pl floor heating tempzone ruler cable.
'floor_heating.tempzone.ruler_cable'- PL_FLOOR_HEATING_TEMPZONE_SHOWER_MAT =
Pl floor heating tempzone shower mat.
'floor_heating.tempzone.shower_mat'- PL_FLOOR_HEATING_TEMPZONE_INSTALLATION_KITS =
Pl floor heating tempzone installation kits.
'floor_heating.tempzone.installation_kits'- PL_FLOOR_HEATING_TEMPZONE_CUSTOM_MAT =
Pl floor heating tempzone custom mat.
'floor_heating.tempzone.custom_mat'- PL_FLOOR_HEATING_TEMPZONE_EASY_MAT_TWIN =
Pl floor heating tempzone easy mat twin.
'floor_heating.tempzone.easy_mat.twin_conductor'- PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL_TWIN_120V =
Pl floor heating tempzone flex roll twin 120v.
'floor_heating.tempzone.flex_roll.twin_conductor.120_v'- PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL_TWIN_240V =
Pl floor heating tempzone flex roll twin 240v.
'floor_heating.tempzone.flex_roll.twin_conductor.240_v'- PL_FLOOR_HEATING_ROUGH_IN_KITS =
Pl floor heating rough in kits.
'floor_heating.rough_in_kits'- PL_FLOOR_HEATING_ENVIRON =
Pl floor heating environ.
'floor_heating.environ'- PL_FLOOR_HEATING_ENVIRON_FLEX_ROLL =
Pl floor heating environ flex roll.
'floor_heating.environ.flex_roll'- PL_FLOOR_HEATING_ENVIRON_EASY_MAT =
Pl floor heating environ easy mat.
'floor_heating.environ.easy_mat'- PL_FLOOR_HEATING_SLAB_HEAT =
Pl floor heating slab heat.
'floor_heating.slab_heat'- PL_FLOOR_HEATING_SLAB_HEAT_MAT =
Pl floor heating slab heat mat.
'floor_heating.slab_heat.mat'- PL_FLOOR_HEATING_SLAB_HEAT_CABLE =
Pl floor heating slab heat cable.
'floor_heating.slab_heat.cable'- PL_FLOOR_HEATING_UNDERLAYMENT =
Pl floor heating underlayment.
'floor_heating.underlayment'- PL_FLOOR_HEATING_UNDERLAYMENT_CORK =
Pl floor heating underlayment cork.
'floor_heating.underlayment.cork'- PL_FLOOR_HEATING_UNDERLAYMENT_CERAZORB =
Pl floor heating underlayment cerazorb.
'floor_heating.underlayment.cerazorb'- PL_FLOOR_HEATING_UNDERLAYMENT_THERMALSHEET =
Pl floor heating underlayment thermalsheet.
'floor_heating.underlayment.thermalsheet'- PL_FLOOR_HEATING_UNDERLAYMENT_PRODESO =
Pl floor heating underlayment prodeso.
'floor_heating.underlayment.prodeso'- PL_LED_MIRROR_MADE_TO_ORDER =
Pl led mirror made to order.
'led_mirror.made_to_order'- PL_FLOOR_HEATING_CONTROL =
Pl floor heating control.
'floor_heating.control'- PL_FLOOR_HEATING_CONTROL_SMARTSTAT =
Pl floor heating control smartstat.
'floor_heating.control.smartstat'- PL_FLOOR_HEATING_CONTROL_EASYSTAT =
Pl floor heating control easystat.
'floor_heating.control.easystat'- PL_FLOOR_HEATING_CONTROL_INTEGRATION =
Pl floor heating control integration.
'floor_heating.control.integration'- PL_FLOOR_HEATING_CONTROL_NSPIRE_TOUCH =
Pl floor heating control nspire touch.
'floor_heating.control.nspire_touch'- PL_FLOOR_HEATING_CONTROL_NSPIRE_TOUCH_WIFI =
Pl floor heating control nspire touch wifi.
'floor_heating.control.nspire_touch_wifi'- PL_FLOOR_HEATING_CONTROL_NJOY_WIFI =
Pl floor heating control njoy wifi.
'floor_heating.control.njoy_wifi'- PL_FLOOR_HEATING_CONTROL_NHANCE =
Pl floor heating control nhance.
'floor_heating.control.nhance'- PL_FLOOR_HEATING_CONTROL_NTRUST =
Pl floor heating control ntrust.
'floor_heating.control.ntrust'- PL_FLOOR_HEATING_CONTROL_NTRUST2 =
Pl floor heating control ntrust2.
'floor_heating.control.ntrust2'- PL_OJ_PROGRAMMABLE_TSTAT_LINES =
OJ Programmable Thermostat product lines (nSpire, nJoy, nHance, nTrust series)
[ PL_FLOOR_HEATING_CONTROL_NSPIRE_TOUCH, PL_FLOOR_HEATING_CONTROL_NSPIRE_TOUCH_WIFI, PL_FLOOR_HEATING_CONTROL_NJOY_WIFI, PL_FLOOR_HEATING_CONTROL_NHANCE, PL_FLOOR_HEATING_CONTROL_NTRUST, PL_FLOOR_HEATING_CONTROL_NTRUST2 ].freeze
- PL_SNOW_MELTING =
Pl snow melting.
'snow_melting'- PL_SNOW_MELTING_MAT =
Pl snow melting mat.
'snow_melting.mat'- PL_SNOW_MELTING_CABLE =
Pl snow melting cable.
'snow_melting.cable'- PL_SNOW_MELTING_CONTROL =
Pl snow melting control.
'snow_melting.control'- PL_ROOF_GUTTER_DEICING =
Pl roof gutter deicing. NOTE: this matches the
ltree_path_slugs/
primary_pl_path_slugscolumns, notslug_ltree— for the roof PL
those two columns diverge (slug_ltree isroof_and_gutter_deicing,
withand). Use ProductLineUrls::ROOF_GUTTER_DEICING when you need
the slug_ltree value. 'roof_gutter_deicing'- PL_ROOF_GUTTER_DEICING_CONTROL =
Pl roof gutter deicing control.
'roof_gutter_deicing.self_regulating_cut_to_length_cable.control'- PL_PIPE_FREEZE_PROTECTION =
Pl pipe freeze protection.
'pipe_freeze_protection'- PL_PIPE_FREEZE_PROTECTION_SELF_REG =
Pl pipe freeze protection self reg.
'pipe_freeze_protection.self_regulating_cable'- PL_PIPE_FREEZE_PROTECTION_CONTROL =
Pl pipe freeze protection control.
'pipe_freeze_protection.self_regulating_cable.pipe_freeze_control'- PL_ROOF_GUTTER_DEICING_SELF_REG =
Pl roof gutter deicing self reg.
'roof_gutter_deicing.self_regulating_cut_to_length_cable'- PL_INFRARED_HEATING_PANELS =
Pl infrared heating panel.
'infrared_heating_panels'- PL_INFRARED_HEATING_PANELS_CONTROL =
Pl infrared heating panel control.
'infrared_heating_panels.control'- PL_TOWEL_WARMER_CONTROL =
Pl towel warmer control.
'towel_warmer.control'- PL_COUNTERTOP_HEATER_CONTROL =
Pl countertop heater control.
'countertop_heater.control'- PL_ALL_CONTROLS =
All control product lines (for electrical plan controls)
[ PL_FLOOR_HEATING_CONTROL, PL_SNOW_MELTING_CONTROL, PL_ROOF_GUTTER_DEICING_CONTROL, PL_PIPE_FREEZE_PROTECTION_CONTROL, PL_INFRARED_HEATING_PANELS_CONTROL, PL_TOWEL_WARMER_CONTROL, PL_COUNTERTOP_HEATER_CONTROL ].freeze
- PL_INFRARED_HEATING_PANELS_LAVA =
Pl infrared heating panel lava.
'infrared_heating_panels.lava'- PL_TOWEL_WARMER =
Pl towel warmer.
'towel_warmer'- PL_TOWEL_WARMER_CLASSIC =
Pl towel warmer classic.
'towel_warmer.classic'- PL_TOWEL_WARMER_CLASSIC_TAHOE =
Pl towel warmer classic tahoe.
'towel_warmer.classic.tahoe'- PL_TOWEL_WARMER_COSMOPOLITAN =
Pl towel warmer cosmopolitan.
'towel_warmer.cosmopolitan'- PL_TOWEL_WARMER_CRYSTAL_ACCESSORIES =
Pl towel warmer crystal accessories.
'towel_warmer.crystal_accessories'- PL_LED_MIRROR =
Pl led mirror.
'led_mirror'- PL_SERVICES =
Pl services.
'services'- PL_SERVICES_SMARTFIT =
Pl services smartfit.
'services.smartfit'- PL_SERVICES_SMARTINSTALL =
Pl services smartinstall.
'services.smartinstall'- PL_SERVICES_SMARTFIX =
Pl services smartfix.
'services.smartfix'- PL_SERVICES_SMARTGUIDE =
Pl services smartguide.
'services.smartguide'- PC_URL_TO_PATH =
===========================================================================
URL to Slug Path mappings (for dynamic lookups) { 'goods' => PC_GOODS, 'services' => PC_SERVICES, 'goods-heating-elements' => PC_HEATING_ELEMENTS, 'goods-heating-elements-heating-cables' => 'goods.heating_elements.heating_cables', 'goods-heating-elements-heating-mats' => 'goods.heating_elements.heating_mats', 'goods-heating-elements-heating-rolls' => 'goods.heating_elements.heating_rolls', 'goods-heating-elements-countertop-heater' => 'goods.heating_elements.countertop_heaters', 'goods-controls' => PC_CONTROLS, 'goods-controls-thermostats' => PC_CONTROLS_THERMOSTATS, 'goods-accessories' => PC_ACCESSORIES, 'goods-accessories-insulations' => PC_ACCESSORIES_INSULATIONS, 'goods-accessories-membranes' => PC_ACCESSORIES_MEMBRANES, 'goods-accessories-installation-kits' => 'goods.accessories.installation_kits', 'goods-spare-parts' => PC_SPARE_PARTS, 'goods-spare-parts-cold-leads' => PC_SPARE_PARTS_COLD_LEADS, 'goods-tools' => PC_TOOLS, 'goods-power' => PC_POWER, 'goods-power-relay-panels' => PC_POWER_RELAY_PANELS, 'goods-power-modules' => PC_POWER_MODULES, 'goods-sensors' => PC_SENSORS, 'goods-towel-warmers' => PC_TOWEL_WARMERS, 'goods-towel-warmers-plug-in' => PC_TOWEL_WARMERS_PLUG_IN, 'goods-towel-warmers-hardwired' => PC_TOWEL_WARMERS_HARDWIRED, 'goods-towel-warmers-dual-connection' => PC_TOWEL_WARMERS_DUAL_CONNECTION, 'goods-mirror-defoggers' => PC_MIRROR_DEFOGGERS, 'goods-mirrors' => PC_MIRRORS, 'goods-radiant-panels' => PC_INFRARED_HEATING_PANELS, 'goods-radiant-panels-plug-in' => PC_INFRARED_HEATING_PANELS_PLUG_IN, 'goods-radiant-panels-hardwired' => PC_INFRARED_HEATING_PANELS_HARDWIRED, 'goods-upgrades' => PC_UPGRADES, 'goods-publications' => PC_PUBLICATIONS, 'goods-publications-installation' => 'goods.publications.installation', 'goods-publications-brochures' => 'goods.publications.brochures', 'goods-publications-catalogs' => 'goods.publications.catalogs', 'goods-publications-sell-sheets' => 'goods.publications.sell_sheets', 'goods-publications-technical-specifications' => 'goods.publications.technical_specifications', 'goods-publications-technical-information' => 'goods.publications.technical_information', 'goods-publications-warranties' => 'goods.publications.warranties', 'goods-publications-wiring-diagrams' => 'goods.publications.wiring_diagrams', 'goods-publications-operation-manuals' => 'goods.publications.operation_manuals', 'goods-publications-project-planners' => 'goods.publications.project_planners', 'goods-kits' => 'goods.kits', 'goods-shower-pan-kits' => 'goods.shower_pan_kits', 'goods-shower-floor-heating-kits' => 'goods.shower_floor_heating_kits', 'goods-shower-waterproofing-accessories' => 'goods.shower_waterproofing_accessories', 'goods-shower-waterproofing-accessories-waterproofing-membranes' => 'goods.shower_waterproofing_accessories.waterproofing_membranes', 'goods-drain-assemblies' => 'goods.drain.assemblies', 'goods-drain-kits' => 'goods.drain.kits', 'goods-drain-grate-covers' => 'goods.drain.grate_covers' }.freeze
- PL_URL_TO_PATH =
Filesystem/URL path for pl url to.
{ # Floor Heating 'floor-heating' => PL_FLOOR_HEATING, 'floor-heating-tempzone' => PL_FLOOR_HEATING_TEMPZONE, 'floor-heating-tempzone-flex-roll' => PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL, 'floor-heating-tempzone-easy-mat' => PL_FLOOR_HEATING_TEMPZONE_EASY_MAT, 'floor-heating-tempzone-cable' => PL_FLOOR_HEATING_TEMPZONE_CABLE, 'floor-heating-tempzone-cable-120-v' => 'floor_heating.tempzone.cable.120_v', 'floor-heating-tempzone-cable-240-v' => 'floor_heating.tempzone.cable.240_v', 'floor-heating-tempzone-installation-kits' => PL_FLOOR_HEATING_TEMPZONE_INSTALLATION_KITS, 'floor-heating-tempzone-custom-mat' => PL_FLOOR_HEATING_TEMPZONE_CUSTOM_MAT, 'floor-heating-tempzone-cable-kits-with-uncoupling-membrane-ntrust2' => 'floor_heating.tempzone.cable.kits_with_uncoupling_membrane.ntrust2', 'floor-heating-tempzone-cable-kits-with-uncoupling-membrane-njoy' => 'floor_heating.tempzone.cable.kits_with_uncoupling_membrane.njoy', 'floor-heating-tempzone-cable-kits-with-fixing-strips-ntrust2' => 'floor_heating.tempzone.cable.kits_with_fixing_strips.ntrust2', 'floor-heating-tempzone-cable-kits-with-fixing-strips-njoy' => 'floor_heating.tempzone.cable.kits_with_fixing_strips.njoy', 'floor-heating-tempzone-flex-roll-twin-conductor-kits-ntrust2' => 'floor_heating.tempzone.flex_roll.twin_conductor.kits.ntrust2', 'floor-heating-tempzone-flex-roll-twin-conductor-kits-njoy' => 'floor_heating.tempzone.flex_roll.twin_conductor.kits.njoy', 'floor-heating-tempzone-easy-mat-twin-conductor-kits-ntrust2' => 'floor_heating.tempzone.easy_mat.twin_conductor.kits.ntrust2', 'floor-heating-tempzone-easy-mat-twin-conductor-kits-njoy' => 'floor_heating.tempzone.easy_mat.twin_conductor.kits.njoy', 'floor-heating-tempzone-flex-roll-twin-conductor-120-v' => PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL_TWIN_120V, 'floor-heating-tempzone-flex-roll-twin-conductor-240-v' => PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL_TWIN_240V, 'floor-heating-tempzone-easy-mat-twin-conductor' => PL_FLOOR_HEATING_TEMPZONE_EASY_MAT_TWIN, 'floor-heating-tempzone-easy-mat-twin-conductor-120-v' => 'floor_heating.tempzone.easy_mat.twin_conductor.120_v', 'floor-heating-tempzone-ruler-cable' => PL_FLOOR_HEATING_TEMPZONE_RULER_CABLE, 'floor-heating-tempzone-thin-cable' => PL_FLOOR_HEATING_TEMPZONE_THIN_CABLE, 'floor-heating-tempzone-ruler-cable-120v' => 'floor_heating.tempzone.ruler_cable.120v', 'floor-heating-tempzone-ruler-cable-240v' => 'floor_heating.tempzone.ruler_cable.240v', 'floor-heating-tempzone-shower-mat-bench' => 'floor_heating.tempzone.shower_mat.bench', 'floor-heating-tempzone-shower-mat-floor' => 'floor_heating.tempzone.shower_mat.floor', 'floor-heating-environ' => PL_FLOOR_HEATING_ENVIRON, 'floor-heating-environ-flex-roll' => PL_FLOOR_HEATING_ENVIRON_FLEX_ROLL, 'floor-heating-environ-easy-mat' => PL_FLOOR_HEATING_ENVIRON_EASY_MAT, 'floor-heating-environ-flex-roll-120-v' => 'floor_heating.environ.flex_roll.120_v', 'floor-heating-environ-flex-roll-240-v' => 'floor_heating.environ.flex_roll.240_v', 'floor-heating-environ-easy-mat-120-v-flat-lead' => 'floor_heating.environ.easy_mat.120_v_flat_lead', 'floor-heating-environ-easy-mat-240-v-flat-lead' => 'floor_heating.environ.easy_mat.240_v_flat_lead', 'floor-heating-slab-heat' => PL_FLOOR_HEATING_SLAB_HEAT, 'floor-heating-slab-heat-mat' => PL_FLOOR_HEATING_SLAB_HEAT_MAT, 'floor-heating-slab-heat-cable' => PL_FLOOR_HEATING_SLAB_HEAT_CABLE, 'floor-heating-underlayment' => PL_FLOOR_HEATING_UNDERLAYMENT, 'floor-heating-underlayment-thermalsheet' => PL_FLOOR_HEATING_UNDERLAYMENT_THERMALSHEET, 'floor-heating-underlayment-prodeso' => PL_FLOOR_HEATING_UNDERLAYMENT_PRODESO, 'floor-heating-rough-in-kits-kits' => 'floor_heating.rough_in_kits.kits', 'floor-heating-control' => PL_FLOOR_HEATING_CONTROL, 'floor-heating-control-smartstat' => PL_FLOOR_HEATING_CONTROL_SMARTSTAT, 'floor-heating-control-easystat' => PL_FLOOR_HEATING_CONTROL_EASYSTAT, 'floor-heating-control-integration' => PL_FLOOR_HEATING_CONTROL_INTEGRATION, # Snow Melting 'snow-melting' => PL_SNOW_MELTING, 'snow-melting-mat' => PL_SNOW_MELTING_MAT, 'snow-melting-cable' => PL_SNOW_MELTING_CABLE, 'snow-melting-control' => PL_SNOW_MELTING_CONTROL, 'snowmelt-powermat' => 'snow_melting.mat.powermat', 'snowmelt-omnimat' => 'snow_melting.mat.omnimat', 'snowmelt-ecomat' => 'snow_melting.mat.ecomat', 'snow-melting-mat-120-v' => 'snow_melting.mat.120_v', 'snow-melting-mat-240-v' => 'snow_melting.mat.240_v', 'snow-melting-cable-120-v' => 'snow_melting.cable.120_v', 'snow-melting-cable-208-v' => 'snow_melting.cable.208_v', 'snow-melting-cable-240-v' => 'snow_melting.cable.240_v', 'snow-melting-cable-277-v' => 'snow_melting.cable.277_v', # Pipe Freeze Protection 'pipe-freeze-protection' => PL_PIPE_FREEZE_PROTECTION, 'pipe-freeze-protection-self-regulating-cable-120-v' => 'pipe_freeze_protection.self_regulating_cable.120_v', 'pipe-freeze-protection-self-regulating-cable-240-v' => 'pipe_freeze_protection.self_regulating_cable.240_v', 'pipe-freeze-protection-constant-wattage-cable' => 'pipe_freeze_protection.constant_wattage_cable', # Roof & Gutter Deicing 'roof-and-gutter-deicing' => PL_ROOF_GUTTER_DEICING, 'roof-and-gutter-deicing-constant-wattage-pre-assembled-plug-in-kits' => 'roof_gutter_deicing.constant_wattage.pre_assembled_plug_in_kits', 'roof-and-gutter-deicing-self-regulating-cut-to-length-cable-120-v' => 'roof_gutter_deicing.self_regulating_cut_to_length_cable.120_v', 'roof-and-gutter-deicing-self-regulating-cut-to-length-cable-240-v' => 'roof_gutter_deicing.self_regulating_cut_to_length_cable.240_v', # Infrared Heating Panels (legacy radiant-panel* keys kept for /products/line redirects) 'infrared-heating-panels' => PL_INFRARED_HEATING_PANELS, 'radiant-panel' => PL_INFRARED_HEATING_PANELS, 'radiant-panel-lava' => PL_INFRARED_HEATING_PANELS_LAVA, 'radiant-panel-lava-glass' => 'infrared_heating_panels.lava.glass', 'radiant-panel-lava-mirror' => 'infrared_heating_panels.lava.mirror', 'radiant-panel-lava-crystal' => 'infrared_heating_panels.lava.crystal', 'radiant-panel-lava-light' => 'infrared_heating_panels.lava.light', 'radiant-panel-ember' => 'infrared_heating_panels.ember', 'radiant-panel-ember-flex' => 'infrared_heating_panels.ember.flex', 'radiant-panel-ember-glass' => 'infrared_heating_panels.ember.glass', 'radiant-panel-ember-mirror' => 'infrared_heating_panels.ember.mirror', # Towel Warmers 'towel-warmer' => PL_TOWEL_WARMER, 'towel-warmer-barcelona' => 'towel_warmer.barcelona', 'towel-warmer-classic' => 'towel_warmer.classic', 'towel-warmer-cosmopolitan' => PL_TOWEL_WARMER_COSMOPOLITAN, 'towel-warmer-control' => 'towel_warmer.control', 'towel-warmer-crystal-accessories' => PL_TOWEL_WARMER_CRYSTAL_ACCESSORIES, 'towel-warmer-crystal-collection' => 'towel_warmer.crystal_collection', # Mirrors 'led-mirror' => PL_LED_MIRROR, 'mirror-defogger' => 'mirror_defogger', # Countertop Heaters 'countertop-heater' => 'countertop_heater', 'countertop-heater-standard' => 'countertop_heater.standard', # Shower Kits 'shower-kits' => 'shower_kits', # Rental Tools 'rental-tools' => 'rental_tools', # Under Desk Heater (support-only) 'under-desk-heater' => 'under_desk_heater', # Services 'services' => PL_SERVICES, 'services-smartfit' => PL_SERVICES_SMARTFIT, 'services-smartinstall' => PL_SERVICES_SMARTINSTALL, 'services-smartfix' => PL_SERVICES_SMARTFIX, 'services-smartguide' => PL_SERVICES_SMARTGUIDE }.freeze
- VALID_LTREE_PATTERN =
Resolve a legacy hyphenated product line segment (e.g. from old routes or +url+ param)
to +slug_ltree+. Uses +PL_URL_TO_PATH+ when present; otherwise treats a single segment
as +tr('-', '_')+ (multi-level hyphen strings must be mapped in +PL_URL_TO_PATH+). /\A[a-zA-Z0-9_]+(\.[a-zA-Z0-9_]+)*\z/
Class Method Summary collapse
- .product_category_path_for(url) ⇒ Object
-
.product_line_path_for(url) ⇒ Object
Look up ltree path for a product line or product category URL Returns the slug path if found in mappings, nil otherwise.
- .slug_ltree_from_legacy_hyphen_url(legacy_segment) ⇒ Object
-
.verify_all ⇒ Object
Verify all hardcoded paths match current database values.
Class Method Details
.product_category_path_for(url) ⇒ Object
426 427 428 |
# File 'app/constants/ltree_paths.rb', line 426 def self.product_category_path_for(url) PC_URL_TO_PATH[url] end |
.product_line_path_for(url) ⇒ Object
Look up ltree path for a product line or product category URL
Returns the slug path if found in mappings, nil otherwise
409 410 411 |
# File 'app/constants/ltree_paths.rb', line 409 def self.product_line_path_for(url) PL_URL_TO_PATH[url] end |
.slug_ltree_from_legacy_hyphen_url(legacy_segment) ⇒ Object
418 419 420 421 422 423 424 |
# File 'app/constants/ltree_paths.rb', line 418 def self.slug_ltree_from_legacy_hyphen_url(legacy_segment) return nil if legacy_segment.blank? s = legacy_segment.to_s result = product_line_path_for(s) || s.tr('-', '_') result.match?(VALID_LTREE_PATTERN) ? result : nil end |
.verify_all ⇒ Object
Verify all hardcoded paths match current database values
431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'app/constants/ltree_paths.rb', line 431 def self.verify_all errors = [] PC_URL_TO_PATH.each do |url, expected_path| pc = ProductCategory.find_by(url: url) if pc.nil? errors << "ProductCategory '#{url}' not found" elsif pc.ltree_path_slugs != expected_path errors << "ProductCategory '#{url}': expected '#{expected_path}', got '#{pc.ltree_path_slugs}'" end end PL_URL_TO_PATH.each do |url, expected_path| pl = ProductLine.find_by(slug_ltree: expected_path) if pl.nil? errors << "ProductLine slug_ltree='#{expected_path}' (from URL key '#{url}') not found" elsif pl.ltree_path_slugs != expected_path errors << "ProductLine '#{url}': expected '#{expected_path}', got '#{pl.ltree_path_slugs}'" end end if errors.empty? puts "✅ All #{PC_URL_TO_PATH.size + PL_URL_TO_PATH.size} ltree slug paths verified!" true else puts "❌ #{errors.size} errors found:" errors.each { |e| puts " - #{e}" } false end end |