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 =
'services'- PC_SHIPPING =
'shipping'- PC_SHIPPING_AND_HANDLING =
'shipping_and_handling'- PC_HEATING_ELEMENTS =
'goods.heating_elements'- PC_HEATING_ELEMENTS_HEATING_CABLES =
'goods.heating_elements.heating_cables'- PC_HEATING_ELEMENTS_CUSTOM_MATS =
'goods.heating_elements.heating_custom_mats'- PC_HEATING_ELEMENTS_COUNTERTOP =
'goods.heating_elements.countertop_heaters'- PC_CONTROLS =
'goods.controls'- PC_CONTROLS_THERMOSTATS =
'goods.controls.thermostats'- PC_ACCESSORIES =
'goods.accessories'- PC_ACCESSORIES_INSULATIONS =
'goods.accessories.insulations'- PC_ACCESSORIES_MEMBRANES =
'goods.accessories.membranes'- PC_SPARE_PARTS =
'goods.spare_parts'- PC_SPARE_PARTS_COLD_LEADS =
'goods.spare_parts.cold_leads'- PC_TOOLS =
'goods.tools'- PC_POWER =
'goods.power'- PC_POWER_RELAY_PANELS =
'goods.power.relay_panels'- PC_POWER_MODULES =
'goods.power.modules'- PC_SENSORS =
'goods.sensors'- PC_TOWEL_WARMERS =
'goods.towel_warmers'- PC_TOWEL_WARMERS_PLUG_IN =
'goods.towel_warmers.plug_in'- PC_TOWEL_WARMERS_HARDWIRED =
'goods.towel_warmers.hardwired'- PC_TOWEL_WARMERS_DUAL_CONNECTION =
'goods.towel_warmers.dual_connection'- PC_MIRROR_DEFOGGERS =
'goods.mirror_defoggers'- PC_MIRRORS =
'goods.mirrors'- PC_RADIANT_PANELS =
'goods.radiant_panels'- PC_RADIANT_PANELS_PLUG_IN =
'goods.radiant_panels.plug_in'- PC_RADIANT_PANELS_HARDWIRED =
'goods.radiant_panels.hardwired'- PC_UPGRADES =
'goods.upgrades'- PC_PUBLICATIONS =
'goods.publications'- 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 =
'floor_heating.tempzone'- PL_FLOOR_HEATING_TEMPZONE_FLEX_ROLL =
'floor_heating.tempzone.flex_roll'- PL_FLOOR_HEATING_TEMPZONE_EASY_MAT =
'floor_heating.tempzone.easy_mat'- PL_FLOOR_HEATING_TEMPZONE_CABLE =
'floor_heating.tempzone.cable'- PL_FLOOR_HEATING_TEMPZONE_THIN_CABLE =
'floor_heating.tempzone.thin_cable'- PL_FLOOR_HEATING_TEMPZONE_RULER_CABLE =
'floor_heating.tempzone.ruler_cable'- PL_FLOOR_HEATING_TEMPZONE_SHOWER_MAT =
'floor_heating.tempzone.shower_mat'- PL_FLOOR_HEATING_TEMPZONE_INSTALLATION_KITS =
'floor_heating.tempzone.installation_kits'- PL_FLOOR_HEATING_TEMPZONE_CUSTOM_MAT =
'floor_heating.tempzone.custom_mat'- PL_FLOOR_HEATING_TEMPZONE_EASY_MAT_TWIN =
'floor_heating.tempzone.easy_mat.twin_conductor'- 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 =
'floor_heating.tempzone.flex_roll.twin_conductor.240_v'- PL_FLOOR_HEATING_ROUGH_IN_KITS =
'floor_heating.rough_in_kits'- PL_FLOOR_HEATING_ENVIRON =
'floor_heating.environ'- PL_FLOOR_HEATING_ENVIRON_FLEX_ROLL =
'floor_heating.environ.flex_roll'- PL_FLOOR_HEATING_ENVIRON_EASY_MAT =
'floor_heating.environ.easy_mat'- PL_FLOOR_HEATING_SLAB_HEAT =
'floor_heating.slab_heat'- PL_FLOOR_HEATING_SLAB_HEAT_MAT =
'floor_heating.slab_heat.mat'- PL_FLOOR_HEATING_SLAB_HEAT_CABLE =
'floor_heating.slab_heat.cable'- PL_FLOOR_HEATING_UNDERLAYMENT =
'floor_heating.underlayment'- PL_FLOOR_HEATING_UNDERLAYMENT_CORK =
'floor_heating.underlayment.cork'- PL_FLOOR_HEATING_UNDERLAYMENT_CERAZORB =
'floor_heating.underlayment.cerazorb'- PL_FLOOR_HEATING_UNDERLAYMENT_THERMALSHEET =
'floor_heating.underlayment.thermalsheet'- PL_FLOOR_HEATING_UNDERLAYMENT_PRODESO =
'floor_heating.underlayment.prodeso'- PL_LED_MIRROR_MADE_TO_ORDER =
'led_mirror.made_to_order'- PL_FLOOR_HEATING_CONTROL =
'floor_heating.control'- PL_FLOOR_HEATING_CONTROL_SMARTSTAT =
'floor_heating.control.smartstat'- PL_FLOOR_HEATING_CONTROL_EASYSTAT =
'floor_heating.control.easystat'- PL_FLOOR_HEATING_CONTROL_INTEGRATION =
'floor_heating.control.integration'- PL_FLOOR_HEATING_CONTROL_NSPIRE_TOUCH =
'floor_heating.control.nspire_touch'- PL_FLOOR_HEATING_CONTROL_NSPIRE_TOUCH_WIFI =
'floor_heating.control.nspire_touch_wifi'- PL_FLOOR_HEATING_CONTROL_NJOY_WIFI =
'floor_heating.control.njoy_wifi'- PL_FLOOR_HEATING_CONTROL_NHANCE =
'floor_heating.control.nhance'- PL_FLOOR_HEATING_CONTROL_NTRUST =
'floor_heating.control.ntrust'- 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 =
'snow_melting'- PL_SNOW_MELTING_MAT =
'snow_melting.mat'- PL_SNOW_MELTING_CABLE =
'snow_melting.cable'- PL_SNOW_MELTING_CONTROL =
'snow_melting.control'- PL_ROOF_GUTTER_DEICING =
'roof_gutter_deicing'- PL_ROOF_GUTTER_DEICING_CONTROL =
'roof_gutter_deicing.self_regulating_cut_to_length_cable.control'- PL_PIPE_FREEZE_PROTECTION =
'pipe_freeze_protection'- PL_PIPE_FREEZE_PROTECTION_SELF_REG =
'pipe_freeze_protection.self_regulating_cable'- PL_PIPE_FREEZE_PROTECTION_CONTROL =
'pipe_freeze_protection.self_regulating_cable.pipe_freeze_control'- PL_ROOF_GUTTER_DEICING_SELF_REG =
'roof_gutter_deicing.self_regulating_cut_to_length_cable'- PL_RADIANT_PANEL =
'radiant_panel'- PL_RADIANT_PANEL_CONTROL =
'radiant_panel.control'- PL_TOWEL_WARMER_CONTROL =
'towel_warmer.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_RADIANT_PANEL_CONTROL, PL_TOWEL_WARMER_CONTROL, PL_COUNTERTOP_HEATER_CONTROL ].freeze
- PL_RADIANT_PANEL_LAVA =
'radiant_panel.lava'- PL_TOWEL_WARMER =
'towel_warmer'- PL_TOWEL_WARMER_CLASSIC =
'towel_warmer.classic'- PL_TOWEL_WARMER_CLASSIC_TAHOE =
'towel_warmer.classic.tahoe'- PL_TOWEL_WARMER_COSMOPOLITAN =
'towel_warmer.cosmopolitan'- PL_TOWEL_WARMER_CRYSTAL_ACCESSORIES =
'towel_warmer.crystal_accessories'- PL_LED_MIRROR =
'led_mirror'- PL_SERVICES =
'services'- PL_SERVICES_SMARTFIT =
'services.smartfit'- PL_SERVICES_SMARTINSTALL =
'services.smartinstall'- PL_SERVICES_SMARTFIX =
'services.smartfix'- 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_RADIANT_PANELS, 'goods-radiant-panels-plug-in' => PC_RADIANT_PANELS_PLUG_IN, 'goods-radiant-panels-hardwired' => PC_RADIANT_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 =
{ # 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' => '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', # Radiant Panels 'radiant-panel' => PL_RADIANT_PANEL, 'radiant-panel-lava' => PL_RADIANT_PANEL_LAVA, 'radiant-panel-lava-glass' => 'radiant_panel.lava.glass', 'radiant-panel-lava-mirror' => 'radiant_panel.lava.mirror', 'radiant-panel-lava-crystal' => 'radiant_panel.lava.crystal', 'radiant-panel-lava-light' => 'radiant_panel.lava.light', 'radiant-panel-ember' => 'radiant_panel.ember', 'radiant-panel-ember-flex' => 'radiant_panel.ember.flex', 'radiant-panel-ember-glass' => 'radiant_panel.ember.glass', 'radiant-panel-ember-mirror' => 'radiant_panel.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
328 329 330 |
# File 'app/constants/ltree_paths.rb', line 328 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
311 312 313 |
# File 'app/constants/ltree_paths.rb', line 311 def self.product_line_path_for(url) PL_URL_TO_PATH[url] end |
.slug_ltree_from_legacy_hyphen_url(legacy_segment) ⇒ Object
320 321 322 323 324 325 326 |
# File 'app/constants/ltree_paths.rb', line 320 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
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'app/constants/ltree_paths.rb', line 333 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 |