Avoiding polymorphic associations in Rails

(sorry for any bad english)

Suppose I have models A, B, C. Each model has one address.

In the book SQL Antipatters: Resolving Database Programming Errors (Chapter 7 - Polymorphic Associations), there is a recipe for avoiding such associations by using a "common super table" (also called a base table or ancestor table).

Polymorphic, it will be:

table addresses:
    id: integer
    parent_type:string  # 'A', 'B' or 'C'
    parent_id: integer

      

I know you can use intersection tables, but the following solution looks more polished:

Instead of polymorphically linking A, B, C to an address, the recipe suggests creating a super-table (Addressing) that only has an id field (surrogate key or pseudo-key). Then other tables refer to addresses. Thus, says the author, "you can rely on foreign keys to ensure the data integrity of your databases." So it would be:

table addressing
    id: integer
table addresses
    id: integer
    addressing_id: integer  (foreign_key)
    zip: string
table a
    id: integer
    addressing_id: integer  (foreign_key)
    name: string
table b
    id: integer
    addressing_id: integer  (foreign_key)
    name: string
table c
    id: integer
    addressing_id: integer  (foreign_key)
    name: string

      

The SQL query will look like this:

SELECT * from a
  JOIN address USING addressing_id
  WHERE a.addressing_id = 1243 

      

QUESTION: How do I code such a script in Rails? I've tried several ways with no success.

+3


source to share


1 answer


Do objects A, B and C have the same address? Or many addresses? From your comment below, it looks like each object has one address.

If each object only has one address, then you can simply put the foreign key in A / B / C objects with an address id. Let House or Office objects have the same address:

class House < ActiveRecord::Base
  belongs_to :address
end

class Office < ActiveRecord::Base
  belongs_to :address
end

      



External address address_id must be specified in tables office

and houses

DB . Thus, you can access the address of an object using or .house.address

office.address

If these objects can have many addresses, the decision depends on the A / B / C objects. If they are related, you can use Single Table Inheritance - Rails supports this pattern well - but without additional information, it's hard to tell which one is best.

+1


source







All Articles