Why there is no automatic relationship discovery

On Feb 9, 2006, at 10:11 AM, Adam F. wrote:

You’re method puts you off the rails. The foreign key is misnamed
with respect to Rails’ naming conventions.

Nope. Still called “id”.

Wrong column. I said the foreign key is misnamed.

There’s nothing that says a foreign key has to be called anything in
particular.

Yes, when you set up the relations in rails, you need to override the
default names, but that’s expected behavior.

How can overriding default behavior be considered expected behavior?
Expected by who?

There’s nothing that says that you have to stick to the default naming
conventions, and there are plenty of exceptions. Doing so doesn’t “put
you off the rails”.

I completely, though respectfully, disagree.

Why do the extra work? Of what benefit is it to use your method, which
will cause extra work and more difficulty in comprehension for each and
every person who needs to work with the schema the Rails code in the
future?

Rails gives you the ability to override so that:

  1. People can’t complain and say “Rails is too restrictive”
  2. It will work with legacy schemas
  3. It’s flexible enough to handle really weird situations

What it does do, is make it simple in the beginning and particularly
in the future, if you just follow the conventions. It’s the difference
between the carrot and stick…

So, IMHO, while what you’re doing is technically supported, it’s
definitely
NOT on the Rails.

P.S. Did you know that you can write routes that will allow you to
direct
incoming requests to controllers with different names? Or that you
can use layouts and views that don’t match the controller names?
The framework is flexible enough to handle this, much as rope is
flexible enough to be used for many purposes, including hanging
oneself. I’m not suggesting there’s never a reason to do any
of the
things mentioned, but I am suggesting that there had better
be some
very good reasons to do so, or you’ve just created extra work
for
yourself, and for each and every person who will support your
app in
the future.


– Tom M.

On Thu, Feb 09, 2006 at 10:29:12AM -0800, Tom M. wrote:

Nope. Still called “id”.

Wrong column. I said the foreign key is misnamed.

My bad then. I misunderstood what you said.

There’s nothing that says a foreign key has to be called anything in
particular.

Yes, when you set up the relations in rails, you need to override the
default names, but that’s expected behavior.

How can overriding default behavior be considered expected behavior?
Expected by who?

Expected by the fact that there’s an API to do so, and doing so
doesn’t break the framework.

There are actually two questions here. One is whether you should ever
override the default naming conventions, and the other is whether it’s
appropriate in this particular case.

It’s not like you’re changing the source - the belongs_to, has_one,
and has_many methods take parameters for changing the defaults. This
isn’t a hack, it’s part of the design, and these are standard options.

I see this as being in the same class as find_by_sql. You’re doing
something that the default configuration doesn’t understand, and that
may or may not be a bad thing, judged on a case by case basis.

There’s nothing that says that you have to stick to the default naming
conventions, and there are plenty of exceptions. Doing so doesn’t “put
you off the rails”.

I completely, though respectfully, disagree.
[…]
So, IMHO, while what you’re doing is technically supported, it’s
definitely NOT on the Rails.

Interesting point, but where’s the line?

What set of constraints defines whether you’re “on the rails” or not?

 *very* good reasons to do so, or you've just created extra work  

for
yourself, and for each and every person who will support your
app in
the future.

I see this as a slightly different case though, because if you’re
defining routes to alternate controllers, you’re bypassing internal
rails structures. When you’re choosing different names for foreign
keys, you’re defining how rails interacts with external entities, in
this case the database. I’d argue that when doing that, you should do
what’s best for the overall design, and that won’t always be “the
rails way”. It’s a point in rails’s favor that it’s accomodating on
this front.

That’s true in the general case. In this particular case, I’m not
convinced either way, and as I pointed out earlier, I often avoid 1:1
associations because of this ambiguity anyway.


- Adam

** Expert Technical Project and Business Management
**** System Performance Analysis and Architecture
****** [ http://www.everylastounce.com ]

[ Adam Fields (weblog) - - entertaining hundreds of millions of eyeball atoms every day ] … Blog
[ Adam Fields Resume ]… Experience
[ Adam Fields | Flickr ] … Photos
[ http://www.aquicki.com/wiki ]…Wiki
[ http://del.icio.us/fields ] … Links

On Feb 9, 2006, at 02:10 PM, Jason P. wrote:

modifying the relationship to a 1:many and bucking the Rails naming
convention causing the need to override the name of the foreign key
for the has_one association. What else do you need to convince you
that the method of using a foreign key as a primary key is
suboptimal? There’s nothing gained over using either the Rails
has_one and/or specifying the foreign key column as UNIQUE and
their are several detriments.

…there are several detriments. Dang.


Jason P.
[email protected]

“As democracy is perfected, the office of president represents,
more and more closely, the inner soul of the people. On some
great and glorious day the plain folks of the land will reach
their heart’s desire at last and the White House will be adorned
by a downright moron.” - H.L. Mencken (1880 - 1956)

On Feb 9, 2006, at 01:43 PM, Adam F. wrote:

That’s true in the general case. In this particular case, I’m not
convinced either way, and as I pointed out earlier, I often avoid 1:1
associations because of this ambiguity anyway.

It’s only when employing the method of constructing 1:1 relationships
that you suggested that problems arise in both modifying the
relationship to a 1:many and bucking the Rails naming convention
causing the need to override the name of the foreign key for the
has_one association. What else do you need to convince you that the
method of using a foreign key as a primary key is suboptimal? There’s
nothing gained over using either the Rails has_one and/or specifying
the foreign key column as UNIQUE and their are several detriments.


Jason P.
[email protected]

“The computer allows you to make mistakes
faster than any other invention, with the
possible exception of handguns and tequila.”

On Thu, Feb 09, 2006 at 02:10:25PM -0600, Jason P. wrote:

It’s only when employing the method of constructing 1:1 relationships
that you suggested that problems arise in both modifying the
relationship to a 1:many and bucking the Rails naming convention
causing the need to override the name of the foreign key for the
has_one association. What else do you need to convince you that the
method of using a foreign key as a primary key is suboptimal? There’s
nothing gained over using either the Rails has_one and/or specifying
the foreign key column as UNIQUE and their are several detriments.

But this is my point - 1:1 relationships are sometimes special, and
they sometimes can’t be expanded to 1:n, because that would make no
sense.

For a highly simplied example, say you’ve got two kinds of orders -
domestic and international. You’ve got some shared fields - order id,
customer id, etc…, but maybe you also have some fields that diverge
dramatically.

One way to do this is to put your shared fields in an “orders” table,
with an id primary key, then make two other tables, domestic_orders
and intl_orders. The latter two tables each have a foreign key
relationship of their primary key to the central orders table, so any
given order will appear either in the domestic_orders table or the
intl_orders table, with a placeholder for the common data in the
orders table, identified by the same key.

In this case, the 1:1 relationships exist to get multiple tables to
share a primary key space, and this makes more sense to me than giving
them each their own primary key and doing the relation as a separate
foreign key. It also avoids an additional lookup, if you already have
the primary key of the order (especially if you’re using the standard
rails convention of addressing items by their primary key instead of
some other key).


- Adam

** Expert Technical Project and Business Management
**** System Performance Analysis and Architecture
****** [ http://www.everylastounce.com ]

[ Adam Fields (weblog) - - entertaining hundreds of millions of eyeball atoms every day ] … Blog
[ Adam Fields Resume ]… Experience
[ Adam Fields | Flickr ] … Photos
[ http://www.aquicki.com/wiki ]…Wiki
[ http://del.icio.us/fields ] … Links

On 2/9/06, Adam F. [email protected] wrote:

But this is my point - 1:1 relationships are sometimes special, and
and intl_orders. The latter two tables each have a foreign key
rails convention of addressing items by their primary key instead of
[ Adam Fields Resume ]… Experience

I understand what you’re getting at with this relationship, but I’m
not sure it’s all that practical. You said using a foreign key as the
primary key avoids an extra lookup - perhaps I’m misunderstanding, but
I think it simply avoids one measley integer column. That hardly
seems worth the trouble of of fighting with the framework when you can
just do ‘belongs_to :order’ and be done with it. I’m not a DB expert,
but is one integer column going to be a big deal? I don’t think so.

In your example I’m not sure it’s the correct domain model anyway,
because it’s very reasonable to have more than one shipment per order,
shipping different products in the order as they become available.
That’s not the point of this whole discussion though of course.
Anyway I simply don’t see any reason to go through the trouble of this
when, following Rails conventions, it takes one extra integer column
and one line of code.

Pat

On Thu, Feb 09, 2006 at 02:12:32PM -0700, Pat M. wrote:

shipping different products in the order as they become available.
That’s not the point of this whole discussion though of course.
Anyway I simply don’t see any reason to go through the trouble of this
when, following Rails conventions, it takes one extra integer column
and one line of code.

First, I’m not talking about “shipments”, per se, but one way to model
order types. I’d assume that if you wanted to also model shipments,
then that would be the kind of thing that would potentially be
convertible from a has_one to a has_many, although I’m not sure what
you gain by not just treating them as a has_many to start with.

As I said - these kinds of 1:1 relationships are “is_a” rather than
“has_a”.

Second, it’s not the extra integer column that’s the problem, it’s the
lookup. By that, I mean - say you have order.id. If you want the
details for the domestic order that goes with it, you can use
domestic_order.id to reference it. If you’re using rails-ish url
schemes, you can do:

/domestic_orders/show/<order.id>

If you’re using a different primary key for the domestic orders, you
have to instantiate the domestic_order object first (even if it
happens automatically for you) and then look up the primary key.

Granted, in most cases, one extra lookup isn’t going to kill you. But
it could be significant if you’re doing high volume.

There are other ways to model this kind of a relationship, but this is
the cleanest one I’ve found from an ER perspective.


- Adam

** Expert Technical Project and Business Management
**** System Performance Analysis and Architecture
****** [ http://www.everylastounce.com ]

[ Adam Fields (weblog) - - entertaining hundreds of millions of eyeball atoms every day ] … Blog
[ Adam Fields Resume ]… Experience
[ Adam Fields | Flickr ] … Photos
[ http://www.aquicki.com/wiki ]…Wiki
[ http://del.icio.us/fields ] … Links

On 2/21/06, Eden B. [email protected] wrote:

Would anyone like to re-open this thread after the recent “vigorous”
discussion
(http://discuss.joelonsoftware.com/default.asp?joel.3.309321.126
) over at Joel on Software? (note: original posting NOT written by Joel)

Please, let’s not re-open this thread, especially because of that JoS
thread. Anyways, this is David’s response to it. What more needs to
be said? If you truly desire it, implement it as a plugin.


  1. Foreign keys are not rich enough to represent most associations.
    Not only can’t they distinguish between 1-1 and 1-M, but they can’t
    hold any customization. So there’s no way to specify has_many
    :active_clients, :conditions => “active = 1”.

And if you can’t represent the vast majority of all associations
through introspection, I’d much rather be explicit about the few that
could have been guessed for the sake of consistency and coherence.

Note that the reverse is the case for attributes. The vast majority of
all attributes accurately describe how we want them presented in the
code since type casting happens automatically. So we only have to
specify the exception.


Rick O.
http://techno-weenie.net

Would anyone like to re-open this thread after the recent “vigorous”
discussion
(http://discuss.joelonsoftware.com/default.asp?joel.3.309321.126)
over at Joel on Software? (note: original posting NOT written by Joel)

Why doesn’t rails take advantage of some basic database functionality to
remove the need to explicitly define relationships and data integrity
for
basic data types (e.g. use field definitions such as int(11),
varchar(60) to
automagically create rails validations). I know DHH and others are
against
business logic in the database, but this seems to be lower level stuff
than
that.

Since the Joel on Software (JOS) thread is long, I will post a couple of
eye
openers here for discussion:

“People are saying you just can’t guess relationships. Well, go figure
out
how Class::DBI::Loader in Perl does it, or go read Randal Schwartz’s
February 2005 Linux Magazine column, where he does it before
Class::DBI::Loader learned how.”

"And if you autogenerate field validation. Yes, developers will need to
override with special validations for passwords and other fields, but
that’s
a lame reason not to do it in the first place. (If you had said “not
enough
time to implement,” I’d have said, “well, of course, that makes sense.)”

Where I stand (as a rails newbie) it seems that (1) relationship auto
discovery and (2) data integrity auto discovery would save a lot of
typing
for most cases. The automatic model could be overridden (as per table
names
and primary keys) in the rare(?) situations where this auto discovery is
incorrect or fails.

I am very curious to see what the rails community here thinks of this.

Perhaps if there is no consensus to add this to the rails core, it could
be
implemented as a plug-in.

Eden

> Would anyone like to re-open this thread after the recent

“vigorous” discussion
> (http://discuss.joelonsoftware.com/default.asp?joel.3.309321.126

Please read :
“Six Ground Rules for ?Rails Sucks? Articles”

http://blog.codahale.com/2006/02/17/six-ground-rules-for-rails-sucks-articles/

Alain

As a side comment out of left field… We could get more DRY if we used
an object-first
ORM instead of ActiveRecord. So, if you could get Og ported to rails,
you could define
your model in Ruby and let Og figure out the db (with all the caveats
that come with that).

b