2

In the app I am building to learn RoR, I have a model "Document" and a model "Business Partner". On the "Document" model, I have 2 fields ("Sender" and "Receiver") referring to the model "Business Partner".

How do I model twice a belongs_to the same target with different fields? What should the migration be?

Related question: how do I model the relationship to it self for business partner? i.e. one company has many business partners, yet can be a business partner too. Note - not to the same record (company A cannot have a relationship to company A (itself).

Dimitri de Ruiter
  • 725
  • 2
  • 7
  • 26

1 Answers1

3

Assuming you've got columns sender_id and receiver_id for the sender and receiver relationships on your Document model (i.e. on your documents table), you can do something like this:

class Document < ActiveRecord::Base
  belongs_to :sender, class_name: "BusinessPartner"
  belongs_to :receiver, class_name: "BusinessPartner"
end

There's no particular migration for this as long as you've got those columns there on the table (if you've named them something else, just replace sender and receiver above by whatever column name minus the _id part).

And then for your BusinessPartner model:

class BusinessPartner < ActiveRecord::Base
  has_many :sent_documents, class_name: "Document", foreign_key: "sender_id"
  has_many :received_documents, class_name: "Document", foreign_key: "receiver_id"
end

Here, sent_documents will fetch all rows in the documents table where sender_id matches the id of the BusinessPartner, and similar for received_documents.

More info in the Rails docs.

Regarding your second question, there is a section of the Rails docs describing this, it is called "Self Joins". However, given that you want to model a many-to-many relationship, you will need a slightly special table arrangement. See this SO answer for some details on how to setup that arrangement. That is actually a somewhat tricky topic in itself, if you're interested in details I'd recommend asking a separate question on it (although that SO post answers it pretty well).

Community
  • 1
  • 1
Chris Salzberg
  • 27,099
  • 4
  • 75
  • 82