On Apr 22, 2006, at 12:10 am, Gerald Anderson wrote:> Good afternoon (as appropriate ; )
>
> I''m having a problem and thought I''d run it past these
forums to
> see if
> there even was a reasonable solution to it.
>
> <snip>
>
> Table parent
> field id1 PK
> field id2 PK
> field other_fields
>
> Table child
> field id1 PK
> field id2 PK
> field other_fields
>
> <snip>
>
> class Parent < ActiveRecord::Base
> set_table_name "parent" # it doesn''t follow naming
convention
> has_one :child
> end
>
> class Child < ActiveRecord::Base
> set_table_name "child"
> belongs_to :parent
> end
>
> I try to get them. . .
>
> parents = Parent.find(:all)
> puts "parents count #{parents.size}" #this works fine
> puts "child count #{parents.child.size}" # not so lucky ; )
>
>
Hi gander
The problem here is that Rails does not support composite keys. It
expects either "id" or another single column that you name. No way
round that unfortunately.
> <snip>
> So, since that''s basic rails models, I figure it''s due to
the fact
> that
> there are no foreign keys defined that it doesn''t build the
> methods. I
> did find the :class_name, :foreign_key, etc arguments for has_one and
> belongs_to, but can''t figure out for the life of me how to handle
this
> situation with these funky compound keys.
>
> Does anybody have any recommendations or pointers where I might find
> some specific information about situations like this?
The foreign keys aren''t actually an issue. Rails doesn''t
analyse the
key constraints in your database to work out the relationships,
because it can''t infer the latter from the former... hence why you
have to use "has_XXX" and "belongs_to".
I can only think of one way round your problem if you want to use the
dynamic Rails methods: create views that construct a virtual unique
id. This will look something (depending on your choice of SQL back-
end) like:
CREATE VIEW parents AS
SELECT (id1 * 10000000 + id2)::int4 as id, <other_fields>
FROM parent
CREATE VIEW children AS
SELECT (id1 * 10000000 + id2)::int4 as id, <other_fields>
FROM child
class Parent < ActiveRecord::Base
has_one :child
end
class Child < ActiveRecord::Base
belongs_to :parent
end
Now, if my sleep-deprived brain is still working, you should be able
to access the data through the views.
You say this is a legacy data. If you only need to read the data,
you''re done. If you want to *write* to the database, it will be more
complex. Your database system will need to support updateable
views. PostgreSQL will certainly handle this - the latest MySQL
MIGHT, but it''s updateable view support is ropey at best. You need
to decompose the virtual ID in the database into id1 and id2. You
didn''t say what meaning the two ids have, and also I don''t
know if
Rails lets you control the id it uses to create new rows, which
together mean it may not be possible.
The bottom line is - supporting composite keys in general is HARD.
The only real way to handle them appears to be to migrate the data,
which is often not possible.
Ashley