STI, Polymorphism and Abstract Classes — Rails

Abstract Base Classes

# app/models/citizen.rbclass Citizen < ApplicationRecord
self.abstract_class = true
end
# app/models/citizen.rbclass Citizen < ApplicationRecord
self.abstract_class = true
def fullname
"#{first_name} #{last_name}"
end
def eligible?
age >= 18
end
end
# app/models/electorate.rbclass Electorate < Citizen
...
end
# app/models/candidate.rbclass Candidate < Citizen
...
end

Single Table Inheritance (STI)

# migration file to add field type to citizendef change
add_column :citizens, :type, :string
end
# app/models/citizen.rbclass Citizen < ApplicationRecord
self.abstract_class = true # remove this line for STI
...
end
# app/models/electorate.rbclass Electorate < Citizen
...
end
# app/models/candidate.rbclass Candidate < Citizen
...
end
Example>> c = Candidate.create
>> c.type
=> "Candidate"
>> Citizen.first
=> #<Candidate:0x231456...>

Polymorphic Associations

# migration file for votesdef change
create_table :votes do |t|
...
t.references :votable, polymorphic: true, index: true
...
end
end
# app/models/vote.rbclass Vote < ApplicationRecord
belongs_to :votable, polymorphic: true
...
end
# app/models/electorate.rbclass Electorate < ApplicationRecord
has_many :votes, as: :votable
...
end
# app/models/candidate.rbclass Candidate < ApplicationRecord
has_many :votes, as: :votable
...
end
Example>> c = Candidate.create
>> c.votes
>> [#<Vote:0x0003437fdd79a91d0 id:1, votable_type: "Candidate", votable_id: 1...>]
>> v = Vote.first
>> v.votable
>> #<Candidate:0x02332fed3903e id:1, ...>
>> Candidate.find(50)
>> ActiveRecord::RecordNotFound: Couldn't find Candidate with 'id'=50...
>> Vote.create!(votable_id: 50, votable_type: "Candidate")
>> # Candidate Load (0.3ms) SELECT "candidates".* FROM "candidates" WHERE "candidates"."id" = $1 LIMIT $2 [["id", 50], ["LIMIT", 1]]
>> ActiveRecord::RecordInvalid: Validation failed: Votable must exist
SQL Shell
>> INSERT INTO votes (votable_id, votable_type, created_at, updated_at) VALUES (50, 'Candidate', '02-05-2019', '02-05-19');
# The above query succeeds even though a candidate with that id doesn't exist.

--

--

--

Human | www.mattwal.com

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

How to install Homebrew on mac PC

5G Core Network Evolution

Dealing with unstructured data (Kafka-Spark-Integration)

Introduction to Java Programming Language :

Liquibase Spanner Extension

Trump appointee tosses president’s Wisconsin election lawsuit

Lets Talk About Oops

Send simple email in Azure DevOps using PowerShell (without any smtp server)

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Olaide Ojewale

Olaide Ojewale

Human | www.mattwal.com

More from Medium

Stuck in the middle

The “new Function” syntax

All things microservices (Part I)

005: When Best Practices Break Down