how to relate models on field other than id

Hi,

The answer might be obvious, but I sure can't find it.

How do I related two tables in a model using a parent (the one side of a one-to-many relationship) field other than "id", and a child (the many side of a one-to-many relationship) field other than "model_name_id"?

Yes, I can write sql, and no, I don't want to. Because it's so much nicer to keep everything in the ROR framework. will_paginate, for example.

Charlie

with foreign_key like

has_many :clients, :foreign_key => :another_column_name

Can you express what you're doing in SQL? I'm assuming both of these other fields are unique in both tables, because if not that'd be a problem. Is there a reason why you don't want to make the relationships based on the ID of the records? Just curious.

Nicholas

sure,

select * from parents, children where parents.column_to_match = children.column_to_match;

I tried that, and I cannot get it to work.

Here is the exact problem. I have two tables, apache_logs and ip_hostnames. Each has a field, "ip", and I would like to relate the two tables based on ip. These tables were created in ROR, so that each has an autoincrement field as its id.

In sql, I just say:

select * from apache_logs, ip_hostnames where apache_logs.ip = ip_hostnames.ip

How do I do this in ROR? like I say, it's a lot better to have all this stuff happen in the ROR framework, for all the code I already have in place -- rather than do a whole new style of pagination just for one set of model relationships / actions / views.

Charlie

charlie caroff wrote:

How do I related two tables in a model using a parent (the one side of a one-to-many relationship) field other than "id", and a child (the many side of a one-to-many relationship) field other than "model_name_id"?

If I understand the question correctly, you can use the foreign_key spec. I assume you'd just add the foreign_key spec to your "belongs_to"

class Child < ActiveRecord::Base   belongs_to :parent_model, :foreign_key => 'parent_key_field' end

http://api.rubyonrails.com/classes/ActiveRecord/Associations/ClassMethods.html http://api.rubyonrails.com/classes/ActiveSupport/CoreExtensions/String/Inflections.html#M000752

You can use foreign_key, see above link for syntax and examples.

:foreign_key - specify the foreign key used for the association. By default this is guessed to be the name of this class in lower-case and _id suffixed. So a Person class that makes a has_one association will use person_id as the default foreign_key.

Example:

     belongs_to :firm, :foreign_key => "client_of"

I hope that helps.

Nicholas

Ok, so if I do this in the console:

logs = apache_logs.find(:all, :include => ip_hostname, :limit => 10)

then

for l in logs puts l.ip_hostname.inspect end

i get

nil nil nil nil nil nil nil nil nil nil

What am I doing wrong?

Charlie

Ok, from your example:

so the related column in the child table is client_of, right?

Is the related column in the parent table, in your example, still the id column?

so that the firm table is, let's say:

id firm_to ...

the person table is

id client_of

and the two tables are related by firm.id -> person.client_of?

What if I don't want to use firm.id, but instead firm.firm_to?

charlie