ActiveRecord stringification

ActiveRecord objects or their attributes often have to be displayed as text. And one specific attribute tends to particularly represent that model or it has to be output more frequently than other attributes. For example, the name of a product or the name of the user.

ActiveRecord default stringification

Since all class instances inherit all methods of Object in Ruby, each object also has a string interpretation. This applies to ActiveRecord too.
The model Person

rails g model Person name:string && rake db:migrate

is stringified by Object#to_s:

puts "Hello #{Person.first}"
# => "Hello #<Person:0x000000028bcf70>"

The person’s name output: Die Ausgabe des Namens der Person:

puts "Hello #{Person.first.name}"
# => "Hello Christian"

occurs quite often, compared to other attributes of Person, since every person feels addressed/ identified by the name.

Overwrite ActiveRecord#to_s

The standard implementation of ActiveRecord#to_s provides no value. Therefore, it is absolutely reasonable to overwrite #to_s if it makes sense:

class Person < ApplicationRecord
  def to_s
    name
  end
end

The message to_s is always sent implicitly during the string interpolation:

puts "Hello #{Person.first}"
# => "Hello Christian"

The implicit string interpolation in the Ruby on Rails templates can also take advantage of the stringification:

# people/show.html.slim
.person = @person
// <div class="person">Christian</div>

The corresponding test:

require 'spec_helper.rb'
RSpec.describe Person, type: :model do
  subject { Person.new name: 'Christian' }

  describe '#to_s' do
    it 'returns the name' do
      expect(subject.to_s).to eq(subject.name)
    end
  end
end

Stringification through delegation

However, if there is no logic involved in the string representation of the object, overwriting by delegation is even more elegant:

class Person < ApplicationRecord
  delegate :to_s, to: :name
end

Especially since there is a Shoulda Matcher, which makes the test more readable and concise:

require 'spec_helper.rb'
RSpec.describe Person, type: :model do
  subject { Person.new name: 'Christian' }

  it { is_expected.to delegate_method(:to_s).to(:name) }
end