belongs_to with composite FK but singular PK?

336 views
Skip to first unread message

Mark Bixby

unread,
Oct 5, 2012, 1:54:58 PM10/5/12
to compos...@googlegroups.com
We are deep in the process of migrating from Rails 2.3.14 / CPK 2.3.2 to Rails 3.2.8 / CPK 5.0.9.  CPK seems to be working for associations where composite foreign keys are being mapped to composite primary keys.

However, we have several belongs_to legacy database tables where the primary key is a single column that corresponds to the concatenated (or otherwise transformed) values of the composite foreign keys.

When we first implemented CPK several years ago in Rails 2.x, my colleague googled up a solution for this problem.  But the solution does not work on Rails 3.x, and my colleague is unable to locate the prior googled reference to see if any Rails 3.x discussion has been added.

In pseudo-code here is what we were doing on Rails 2.x:

class PerPay < ActiveRecord::Base
  belongs_to :leave_grp,
    :primary_key => :pk_di_lg,  # non-existent col refers to dynamic finder class method find_by_pk_di_lg
    :foreign_key => [:di_no, :leave_group]
end

class LeaveGrp < ActiveRecord::Base
  set_primary_key :codex_4  # di_no + leave_group

  def self.find_by_pk_di_lg(*args)
opts = args.extract_options!
pk_di, pk_lg = args.first  # :foreign_key is an array in the belongs_to
find(('%02d' % pk_di) + pk_lg)
  end
end

In PerPay, :di_no is integer (i.e. 39) and :leave_group is string (i.e. 'AV').    In LeaveGrp, the :codex_4 primary key is a 4-char string, i.e. '39AV'.  By specifying the belongs_to :primary key to be a non-existent column on Rails2, the dynamic finder in the target table would be invoked, and we would concatenate the multiple foreign keys passed by CPK, then do a find.

This does not work on Rails3.  Rather than invoking the LeaveGrp.find_by_pk_di_lg() method, SQL gets generated referring to the non-existent pk_di_lg column, which fails.

Changing the legacy LeaveGrp table is not an option.  For performance purposes, we really need to access that table by the true :codex_4 primary key.

One solution would be to abandon the belongs_to association entirely and just make this a regular method within the PerPay model to retrieve the LeaveGrp row, but we prefer to stay as Rails-ish as possible and Rails encourages associations.

Thanks...

cfis

unread,
Nov 22, 2012, 1:23:44 AM11/22/12
to compos...@googlegroups.com
Hi Mark,

Sounds like you have an interesting problem.  Where you looking for some particular change in CPK?  Sounds like your issues are being caused by changes to ActiveRecord...maybe reimplement how dynamic finders used to work?

Charlie
Reply all
Reply to author
Forward
0 new messages