Skip to main content

Step 8

Step 8: Polymorphic Relationshipsโ€‹

View the Diff

Let's introduce the concept of a Note. A Note can belong to a Department, an Employee, or a Team. For this, we'll need to introduce the concept of polymorphism.

idnotable_idnotable_typebody
11EmployeeA Sample Note!
21DepartmentAnother Sample Note!
31TeamA Third Sample Note!

The Rails Stuff ๐Ÿš‚โ€‹

$ rails generate model Note notable:references{polymorphic}:index
$ bin/rails db:migrate

Make sure to add the corresponding model relationships:

# app/models/employee.rb
has_many :notes, as: :notable
# app/models/team.rb
has_many :notes, as: :notable
# app/models/department.rb
has_many :notes, as: :notable

# app/models/note.rb
belongs_to :notable, polymorphic: true

Finally, make sure to edit your seed file - check out the diff to see the necessary adjustments.

The Graphiti Stuff ๐ŸŽจโ€‹

$ bin/rails g graphiti:resource Note body:string

Let's create our NoteResource:

class NoteResource < ApplicationResource
attribute :body, :string

filter :notable_id, :integer
filter :notable_type, :string, allow: %w(Employee Department Team)

polymorphic_belongs_to :notable do
group_by(:notable_type) do
on(:Employee)
on(:Team)
on(:Department)
end
end
end

And corresponding associations:

# app/resources/employee_resource.rb
polymorphic_has_many :notes, as: :notable
# app/resources/team_resource.rb
polymorphic_has_many :notes, as: :notable
# app/resources/department_resource.rb
polymorphic_has_many :notes, as: :notable

Digging Deeper ๐Ÿงโ€‹

When defining a polymorphic relationship for our API, we're saying "grab all the parent records, group them by a type column, and execute different queries for each type". This way records with notable_type == 'Employee' can hit the employees table, but records with notable_type == 'Department' could in theory load from a different API altogether.

Each of the on lines defines a new belongs_to association. That means you can customize just like always:

on(:Team).belongs_to :team, resource: SomeCustomTeamResource do
# assign {}
# link {}
# ... etc ...
end

NEXT - Step 9: Polymorphic Resources ยป