Gray Kemmey Gray Kemmey - 3 months ago 8
Ruby Question

Defining "has_many through: assocation" with scoped conditionals in the through model

I have a schema that looks something like this:

create_table "customers" do |t|
t.integer "customer_number"
end

create_table "past_payments" do |t|
t.integer "customer_number"

t.datetime "transaction_date"
t.integer "arbitrary_sequence_number"
end

create_table "payment_details" do |t|
t.datetime "transaction_date"
t.integer "arbitrary_sequence_number"
end


TL;DR from the schema - A Customer is associated with a past_payment through a primary/foreign key. And a PastPayment is associated with a single PaymentDetail when their transaction_date AND arbitrary_sequence_number are equal. Payments and Details have no formal primary/foreign key relationship.

That gives me the following ActiveRecord models:

class Customer < ActiveRecord::Base
has_many :past_payments, foreign_key: :customer_number, primary_key: :customer_number

has_many :payment_details, through: :past_payments # unfortunately, broken

Answer

You can leverage this gem to better handle "composite primary keys" in ActiveRecord: https://github.com/composite-primary-keys/composite_primary_keys

class Customer < ActiveRecord::Base
  has_many :past_payments, foreign_key: :customer_number, primary_key: :customer_number

  has_many :payment_details, through: :past_payments # this works now
end

class PastPayment < ActiveRecord::Base
  has_one :payment_detail, foreign_key: [:transaction_date, :arbitrary_sequence_number],
                           primary_key: [:transaction_date, :arbitrary_sequence_number]
end