how to safely replace all whitespaces with underscores with ruby?

If you're interested in getting a string in snake case, then the proposed solution doesn't quite work, because you may get concatenated underscores and starting/trailing underscores.

For example

1.9.3-p0 :010 > str= "  John   Smith Beer "
  => "  John   Smith Beer " 
1.9.3-p0 :011 > str.downcase.tr(" ", "_")
  => "__john___smith_beer_"

This solution below would work better:

1.9.3-p0 :010 > str= "  John   Smith Beer "
  => "  John   Smith Beer " 
1.9.3-p0 :012 > str.squish.downcase.tr(" ","_")
  => "john_smith_beer" 

squish is a String method provided by Rails


Pass '_' as parameter to parameterize(separator: '-'). For Rails 4 and below, use str.parameterize('_')

Examples:

with space

str = "New School"
str.parameterize(separator: '_')

=> "new_school"

without space

str = "school"
str.parameterize(separator: '_')

=> "school"

You can also solve this by chaining underscore to parameterize.

Examples:

with space

str = "New School"
str.parameterize.underscore

=> "new_school"

without space

str = "school"
str.parameterize.underscore

=> "school"

The docs for tr! say

Translates str in place, using the same rules as String#tr. Returns str, or nil if no changes were made.

I think you'll get the correct results if you use tr without the exclamation.