Why doesn't rails provide a useful to_s on most objects?

Whenever I create a ruby object, I always try to provide a useful to_s. I’ve noticed that most people — especially in Rails and other Gems that I use — don’t do this. This is not a complaint or a judgment. I’ve just always been curious. I’m sure there is a very good reason and I’d like to know what it is.

Sometimes I make the to_s something that would be useful in a UI, so I can type, for example, #{user} instead of #{user.name}. More often, it’s something that would be useful when debugging, whether in the console or in a debugger, to tell me what objects are in an array or what’s the current state of an object.

For example, I often wish that ActiveModel::Errors would tell me why my model is invalid (e.g. ‘name can’t be blank’) instead of “#ActiveModel::Errors:0x00007f89993af938”.

Is there a reason that folks don’t provide a useful to_s?

1 Like

Agree with you 100%. I usually provide some sort of reasonable to_s method so when using in string interpolation, ERB templates, etc I can just reference the object and get something that looks reasonable. If the object is an ActiveRecord object the alias_attribute method is useful for this. For example:

class User < ApplicationRecord
  alias_attribute :to_s, :name

I do want to note that I think to_s should be reserved for outputting something reasonable for a user to digest. You mentioned making it useful for debugging. I would suggest if you want to improve the debugging output you override inspect as that is the method consoles general call to stringify an object.

I don’t agree with your to_s usage, because most tables does not have name column. and #{user.name} is the better descriptive than #{user} IMO.

but the e_a’s example seems good to solve.

The variable watch window in Rubymine, for example, calls to_s on variables. Plus, I find the default inspect useful and don’t want to replace it.

I used to use to_s often, but I found it more difficult to refactor code that used it.

1 Like

Hi Kevin,

#to_s is in use everywhere That should give a readable String

you can redef #inspect you can redef #to_json

I don’t think #to_s should have a default representation for debugging - some objects have a meaningful string representation, others don’t.

I would however love to have a pretty printed console representation for more types of Rails objects like what is done for ActiveRecord.


ActiveModel::Error does override #inspect:

You could make a PR to also implement it for ActiveModel::Errors.