0

I am having two classes: Topic and Buy::Topic. The latter is a sub class of the former, through a foreign key (Buy::Topic.topic_id == Topic.id). So essentially this is using class table inheritance pattern.

Buy::Topic has its own id and the foreign key topic_id pointing to the parent Topic object.

However I would like to make sure the id of Buy::Topic to be the same as the topic_id from the parent like this:

#<Topic id: 22598> with #<Buy::Topic id: 22598, topic_id:22598

Is this possible in Rails? This is better for SEO purposes, and will make it easier in dealing with Cancan's load_and_authorize_resource (sometimes cancan use the wrong id of the two to find stuffs).

UDPATE:

This schema has been set and done for a long time, so it's unlikely to change it to STI now.

lulalala
  • 17,572
  • 15
  • 110
  • 169
  • It feels like STI would be a better choice if you want the id's to match up. You can always define the Buy::Topic to be a special case of Topic... – Marc Talbot Mar 06 '12 at 04:27
  • yeah I thought about it, and the reason is that the sub class has too many other fields. – lulalala Mar 06 '12 at 04:30
  • ...and that's bad because? To quote Knuth "premature optimization is the root of all evil". Storage space is ridiculously cheap. If your core requirement is "let the id's be the same" for SEO, then optimize for that, not for storage. – Marc Talbot Mar 06 '12 at 04:59

2 Answers2

1

Doing this will actively destroy your CTI and might even create an anti-pattern!

My argument is that if,

Buy::Topic.id == Buy::Topic.topic_id == Topic.id

then you create a one-to-one relationship between Buy::Topic and Topic.

This means that no other class can be composed of Buy::Topic because the id could clash with some Topic.id.

Since Buy::Topic is a subclass of Topic, you really only have a single conceptual entity now. Except you have two tables and some crazy indexes to get you there.

Ian Bishop
  • 5,185
  • 3
  • 26
  • 37
  • Yes, it is a one-to-one relationship. I don't get the clash part of the argument. – lulalala Mar 06 '12 at 04:41
  • CTI is generally used to basically emulate composition for relational databases. ie: You have an individual and an organization, both of which have common address-related fields. You can then make a contact table which can be linked to by both of them. This feature is lost, making `Buy::Topic` only usable by `Topic`. See more here: http://laughingmeme.org/2004/08/14/mysql-and-the-case-for-class-table-inheritance/ – Ian Bishop Mar 06 '12 at 04:50
  • Well, Buy::Topic is some extension to Topic, so it makes no sense to have Buy::Topic not belonging to Topic. And since this has been done and set before i started to maintain it, I won't be changing it. – lulalala Mar 08 '12 at 02:10
0

Dude, this is okay, just call your column topic_parent_id and create association like this:

belongs_to :parent, :class_name => 'Topic', :foreign_key => 'topic_parent_id'

vorobey
  • 4,401
  • 3
  • 18
  • 20