Inconsistency between String#camelize and ActiveSupportInflector.camelize

These two camelize methods works quite similar, but there is a subtle difference to make first letter downcase like below.

'active_support'.camelize(:lower) # => 'activeSupport'
ActiveSupport::Inflector.camelize('active_support', false) # => 'activeSupport'

The tricky part is when we pass :lower as the second argument to Inflector.

ActiveSupport::Inflector.camelize('active_support', :lower) # => 'ActiveSupport'

In this case it ignores :lower argument without any warning. This might cause a problem.

I think ActiveSupport::Inflector.camelize should either accept :lower just like String#camelize or print warning that it might be wrong usage.

1 Like

The two methods take different arguments. String#camelize takes a symbol (:upper or :lower), but ActiveSupport::Inflector.camelize takes a bool. You can see this in the implementation: rails/inflections.rb at 5f3ff60084ab5d5921ca3499814e4697f8350ee7 · rails/rails · GitHub

In this case, ActiveSupport::Inflector.camelize('active_support', :lower) is actually treated as the same as ActiveSupport::Inflector.camelize('active_support', true) (which is probably not what you expect!).

Just to confirm my understanding, is the suggestion here that ActiveSupport::Inflector.camelize either

  1. Support :upper and :lower as arguments as well as true and false, or
  2. Print a warning if the second argument is anything other than a boolean

I think both are reasonable and would lead toward option 1.

1 Like

Made a PR for option 1. Handle Symbol arguments in `ActiveSupport::Inflector.camelize` by ghiculescu · Pull Request #41313 · rails/rails · GitHub

Update: looks like this’ll be fixed in Rails 6.2 :slight_smile: