has_many with different primary key

I've got quite the ActiveRecord challenge, any help would be
appreciated.

  In my current project Companies can have many reviews.

class Company < ActiveRecord::Base
  has_many :reviews, :as => :reviewable
end

  However, my company table, I have two different IDs to identify my
company.

id - This is the typical id we use for normal stuff
other_company_id - This is the id we use for reviews (on a shared db)

  Don't ask why, we're integrating two systems. So, rather then using id
as the primary key for the relationship (as the above code would do) I
want to use other_company_id for the primary key. It'd be great if I
could do this:

class Company < ActiveRecord::Base
  has_many :reviews, :as => :reviewable, :with_primary_key =>
:other_company_id
end

  It would then use the other_company_id to lookup and create reviews.
Unfortunately, Rails has no such option.

  There has to be someone else out there that has run into this
limitation. Thanks in advance for the help.

Gregg Pollack
RailsEnvy.com

Do you mean :foreign_key => “other_company_id”?

Nope, the opposite of that. Rather then specifying a different foreign
key, I want to specify a different primary key from the has_many side of
the relationship.

Another way to write what I'm trying to do (but it doesn't work) is:

class Company < ActiveRecord::Base
  has_many :reviews, :as => :reviewable, :dependent => :destroy do
    Company.set_primary_key "hr_company_id"
  end
end

I want to have a different primary key when referencing the
relationship.

Anyone?

Ryan Bigg wrote:

So there’s a field inside the reviews table that is hr_company_id and represents an ID for the linked company? :foreign_key does exactly what you’re explaining unless I’m getting it horribly wrong or misinterpreting what you’re saying.

Say I have blogs and comments with model blog has_many :comments and the comments table has a field called hr_blog_Id, I specify :foreign_key => “hr_blog_id” on the has_many and it works.

Ryan,

:foreign_key allows you to specify a different field for the
"belongs_to" side of the relationship. What I'm talking about is the
has_many side.

Company has two primary_keys which it needs to use at different times.
Some tables it uses "id" for the relationship, some tables it uses
"hr_company_id" for the relationship.

On the Reviews side (the belongs_to side of the relationship), which is
a polymorphic table, the foreign_key is ALWAYS reviewable_id. This
foreign key does not need to change, so I wouldn't want to specify a
different foreign_key.

What I need to specify is a different primary key for the relationship
to be referenced by. Typically when you need to use a different primary
key on a table you call "set_primary_key".

I want to have a different primary key, just when referencing this
relationship.

companies.hr_company_id (primary key - has_many side) =>
reviews.reviewable_id (foreign_key belongs_to side)

I'm pretty sure I'm not going to be able to do this without monkey
patching ActiveRecord somehow.

-Gregg

Ryan Bigg wrote:

You are correct, you can set it on both sides to identify a different
foreign_key. Unfortunately I don't need to change the foreign_key, I
need to change the primary key.

Anyone else want to chime in here?

Ryan Bigg wrote:

I've been struggling with this problem as well. a possible solution to
this might be to create a new class for the secondary primary key,
something like:

Company2 << Company
  set_primary_key :hr_primary_key_id
end

and then use Company2 when you want to get the alternate has_many
association.

Something else which has occured to me, is that maybe you could use a
habtm association. but then you'd need to make access Company as a
join model for this particular operation and you'd need to have
something else on the left of it.

not sure how much any of this helps as its purely hypothetical but i'm
interested to see where this discussion goes.

Cheers,
-vince

Vincey,

   Thanks for the response. I've considered using a subclass, which
does get around the problem in some circumstance. Unfortunately in my
case, I'm using a polymorphic association.

   I would need to somehow define a different "type" when the
polymorphic association gets stored, because it would store the subclass
type as "reviewable_type = Company2". So I would need some way to
override the class name in the polymorphic association. I haven't found
this is possible.

   I wonder how hard it would be to patch rails to do:

   has_many :reviews, :as => :reviewable, :with_primary_key =>
:hr_company_id

-Gregg

vincey wrote:

Hi,

Facing the same problem here but with the simpler case of
non-polymorphic has_many association. We use the standard 'id' for most
associations but we also have a 'uuid' field that I need to associate
on. Using your Company/Review example it would be like this:

companies has a uuid column as uniqe index
reviews has a company_uuid column

Company has_many :reviews, :foreign_key => "company_uuid"

Now, I'd need reviews.company_uuid to join on companies.uuid and not
companied.id.

Using a new class to set_primary_key is not really an option because
instantiated Company objects through activerecord finders won't work for
this association.

Any other suggestions/ideas?

I am working on this right now, I'll keep you posted of my finding.

Colin.

Gregg Pollack wrote:

Found this on lighthouse
http://rails.lighthouseapp.com/projects/8994/tickets/765-primary_key-option-for-belongs_to

seems they are going that direction for being able to specify
:primary_key is associations.

Colin.

Hey Gregg Pollack,

Have you found the solution for the issue.
I'm also facing the same problem and found this is the ditto problem.
Would like to hear if you found some solution to it ??

Thanks
Akshay

Hey Gregg Pollack,

Have you found the solution for the issue.
I'm also facing the same problem and found this is the ditto problem.
Would like to hear if you found some solution to it ??

has_many takes a :primary_key option.

Fred

Hey Frederick,

Thats what i did and thought its working fine after going through the
documentation. But surprisingly its not working that way its supposed to
be :frowning:

Thanks

Frederick Cheung wrote: