Forum: Ruby on Rails STI and foreign_key problem

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Peer A. (Guest)
on 2006-04-07 07:13
Hi,

I am trying to use STI since my classes only vary by one column in the
database.
Here is the structure (names have been changed to protect the innocent):


      Case
    /       \
Registered  Initial
    \       /
     Children

A registered case has additional information than an initial case (I
realize I could just set a flag to separate them, but there is a good
reason to separate them), but both need to be related to the children
table.  Here is the model code:

class Case < ActiveRecord::Base
end

class Registered < Case
  has_many :children, :foreign_key => "case_id"
end


class Initial < Case
  has_many :children, :foreign_key => "case_id"
end

class Child < ActiveRecord::Base
  belongs_to :initial
  belongs_to :registered
end


When I attempt to access the children attribute via an Initial object I
get an unknown column exception and the dump shows the sql is trying to
select "initial_id" from the children table. This despite the fact I
specified the foreign key of 'case_id' in the Initial model.

This has been driving me crazy this evening.  All searches for help have
come up empty.  Anyone help would be greatly appreciated.

Thanks!

Peer
Daniel -. (Guest)
on 2006-04-07 08:00
(Received via mailing list)
Hi Peer,

With your structure you can add the line
  has_many :children, :foreign_key => "case_id"
to the case definition.

The reason that the sql is looking for the initial_id is because the
class
Child belongs to it.

There are 3 options,

1.  Include an initial_id and a registered_id to your children table
If there is a requirement that it belongs to an inital or registered
case
only include that in the validation of the child object.

2. Include a case_id in the Child table and change the Child class
definition to:
class Child < ActiveRecord::Base
  belongs_to :initial, :foreign_key => 'case_id'
  belongs_to :registered, :foreign_key => 'case_id'
end

I don't know the wisdom of doing this one.  Having never tried it it may
milage may be non-existant.

3. Make Child polymorphic.  Then you can associate children with
anything.

I would tend to go for option 3.  It's cleaner and allows for the
future.
Daniel -. (Guest)
on 2006-04-07 08:03
(Received via mailing list)
Sorri to repost so soon,

Looking at your associations, you already have the case_id in the child
table.

With STI initial and registered *ARE* cases.  So you can just use the
case_id.  When you query it you can decide.

child.case.type will tell you what class it is.
Peer A. (Guest)
on 2006-04-07 15:18
Daniel ----- wrote:
> Sorri to repost so soon,
>
> Looking at your associations, you already have the case_id in the child
> table.
>
> With STI initial and registered *ARE* cases.  So you can just use the
> case_id.  When you query it you can decide.
>
> child.case.type will tell you what class it is.

This is how I thought it was designed to work and how I thought I had
the classes configured to work just like you described here.  Am I
missing something?

Peer
Peer A. (Guest)
on 2006-04-07 17:00
Peer A. wrote:
> Daniel ----- wrote:
>> Sorri to repost so soon,
>>
>> Looking at your associations, you already have the case_id in the child
>> table.
>>
>> With STI initial and registered *ARE* cases.  So you can just use the
>> case_id.  When you query it you can decide.
>>
>> child.case.type will tell you what class it is.
>
> This is how I thought it was designed to work and how I thought I had
> the classes configured to work just like you described here.  Am I
> missing something?
>
> Peer

I figured out what I was doing wrong and I don't think I want to mention
it in public. But since some nuby (like me) might do the same thing in
the future I guess it is only right that I do.

When I initially made the system I made separate models for Initial and
Registered then I tried to switch it to STI.  I know now that I setup up
the STI correclty.  However, I redeclared my classes, Initial and
Registered, in the new case.rb file and did not delete the old model
files.  Parts of it were working so I thought everything was alright,
but I was still using the old models that weren't configured properly
and hence the errors.  Once I removed the old files and added the link
to the case model in application.rb everything worked just fine.
Whoops!

Thanks for listening (and helping Daniel!)

Peer
This topic is locked and can not be replied to.