I recently finished up my mod3 project called Belay Land. One of the key aspects of this project was learning how to create a backend that would allow my users to form belay partnerships with other users. After doing some research I came across self-referential m:n relationships and it was exactly what I needed.
The first step was to migrate the two tables that would be used to make the relationship.
Partnerships is my join table. I added in a partnership status column and set the default to pending in order to keep track of the partnership being accepted by the receiving party.
create_table "partnerships", force: :cascade do |t| t.integer "requestor_id" t.integer "receiver_id" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false t.string "partnership_status", default: "pending" end
And of course my users table (slimmed down for readability).
create_table "users", force: :cascade do |t| t.string "username" end
The next step was to set up the relationships between my models. I created a User and Partnership model. Giving them the follow relationship I was able to make a connection between users.
class User < ApplicationRecord has_many :partnerships_as_requestor, foreign_key: :requestor_id, class_name: :Partnership has_many :partnerships_as_receiver, foreign_key: :receiver_id, class_name: :Partnership
class Partnership < ApplicationRecord belongs_to :requestor, class_name: :User belongs_to :receiver, class_name: :User
This relationship essentially creates subclasses of the User class in order to allow users to be a receiver or a requestor of a partnership request.
I added a serializer to my User model in order to have access to these partnerships being created.
class UserSerializer includes FastJsonapi:ObjectSerializer attributes :partnerships_as_requestor, :partnerships_as_receiver
Overall my biggest challenge was not developing my backend enough. I found myself having to dig through my data a bit more on the frontend than I would of liked to in order to access the partnerships. I would definitely recommend writing yourself a few methods in your backend to fix this. One suggestion I would do is to create a method to make a list of all of your partnerships with the status of accepted.
I hope this is helpful for someone trying to create a self-referential m:n relationship, goodluck!