Using Ruby >= 2.7 with String#partition
Provided you aren't passing in a URI scheme like 'https://' as part of your string, you can do this as a single method chain with String#partition and String#tr. Using Ruby 3.0.2
'localhost:3000/filter-shoes-color-white'.partition(?/).
map { _1.match?(/^\/$/) ? _1 : _1.tr(?/, ?-) }.join
#=> "localhost:3000/filter-shoes-color-white"
This basically relies on the fact that there are no forward slashes in the first array element returned by #partition, and the second element contains a slash and nothing else. You are then free to use #tr to replace forward slashes with dashes in the final element.
If you have an older Ruby, you'll need a different solution since String#partition wasn't introduced before Ruby 2.6.1. If you don't like using character literals, ternary operators, or numbered block arguments (introduced in Ruby 2.7), then you can refactor the solution to suit your own stylistic tastes.