> For the complete documentation index, see [llms.txt](https://crystal-garage.gitbook.io/lustra-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://crystal-garage.gitbook.io/lustra-docs/model/polymorphic-models-vs-associations.md).

# Polymorphic Models vs Associations

Lustra has two features with similar names:

| Feature                  | Database shape                                                                                 | Use when                                                          |
| ------------------------ | ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| Polymorphic associations | One child table stores `<name>_id` and `<name>_type` and can point to different parent tables. | A shared child record can belong to several parent model types.   |
| Polymorphic models       | Several Crystal model classes share one table and are distinguished by a type column.          | One table stores different subclasses of the same logical record. |

This distinction is important for Rails users. Rails calls the first feature "polymorphic associations". Rails usually calls the second pattern "single table inheritance" or STI. Lustra uses the name "polymorphic models" for the shared-table model feature.

## Polymorphic Associations

A polymorphic association keeps parent records in separate tables:

```
employees
products
pictures
  imageable_id
  imageable_type
```

The child model belongs to one of several possible parent models:

```crystal
class Picture
  include Lustra::Model

  belongs_to imageable : Employee | Product, polymorphic: true
end
```

Use this for comments, pictures, attachments, reactions, audit entries, or any other child record that can be attached to different parent tables.

See [Polymorphic Associations](/lustra-docs/model/associations/polymorphic-associations.md).

## Polymorphic Models

Polymorphic models keep different Crystal classes in one shared table:

```
events
  type
  message
  user_id
  repository_id
```

The stored type decides which Crystal class should be instantiated:

```crystal
abstract class Event
  include Lustra::Model

  polymorphic through: "type"
end

class UserEvent < Event
end

class RepositoryEvent < Event
end
```

Use this when records are variants of one concept and mostly share the same table structure.

See [Polymorphic Models](/lustra-docs/model/polymorphic-models.md).

## Quick Rule

If one row points to many possible parent tables, use a polymorphic association.

If many Crystal classes are stored in one table, use polymorphic models.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://crystal-garage.gitbook.io/lustra-docs/model/polymorphic-models-vs-associations.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
