0

I am trying to wrap my head around how I am going to be able to have a has_many (or has_one in my case) association with a compound foreign_key.

For my example Assume this:

Imagine I am managing relationships between sellers and buyers, there is an initial contract between them and after that any amount of invoices. So the models look like this:

class Invoice
  belongs_to :seller
  belongs_to :buyer
end
class Seller
  has_many :contracts
  has_many :invoices
end
class Buyer
  has_many :contracts
  has_many :invoices
end
class Contract
  belongs_to :seller
  belongs_to :buyer
end

For every invoice there is one initial contract (defined by the seller and the buyer). I'm aware that there is all kinds of solutions to build a query that achieves that. Ideally though I want to take care of preloading/joining the contract for a list of invoices to avoid N+1 problems:

class Invoice
  belongs_to :seller
  belongs_to :buyer

  has_one :contract # options go here
end

EDIT: The schema is what it is. Solutions that require a schema change unfortunately is not an option.

leifg
  • 8,668
  • 13
  • 53
  • 79

1 Answers1

1

Just make the invoice belong to the contract and get the buyer and seller from that.

class Invoice
  belongs_to :contract
end

Then get the invoices through contacts...

class Buyer
  has_many :contracts
  has_many :invoices, through: :contracts
end

class Seller
  has_many :contracts
  has_many :invoices, through: :contracts
end
dbugger
  • 15,868
  • 9
  • 31
  • 33
  • Doesn’t that imply I need to change the Schema? – leifg Jan 09 '21 at 16:07
  • Yes -- which will simplify the application and make it easier to ensure data integrity. Your current schema likely has duplicate path ways to same data which will lead to errors down the road. Also compound keys are rarely a good idea and really don't play nicely in rails. – dbugger Jan 09 '21 at 18:19
  • Unfortunately the schema is what it is. As my example is a simplification there are valid functional reasons why the schema won't change (e.g. there is not necessarily always a contract). – leifg Jan 09 '21 at 19:38
  • Not sure what you're expecting receive in the way of answers -- building on top of an unusual, non-normalized data model is at best an art, at worst a never ending set of headaches. Rails being an opinionated framework does not make it any easier. – dbugger Jan 09 '21 at 19:48