# ActiveMDX Model Basics

```javascript
import { Model, Collection } from "active-mdx"

const collection = new Collection()

class Epic extends Model {
  stories() {
    return this.hasMany(Story, { heading: "stories" })
  }
}

class Story extends Model {}
```

We register models with a collection

```javascript
collection.model("Story", Story)
```

A Model is a class that represents a single type of MDX document in your file tree. Generally, for the model `Story` we expect the story documents to live in a folder called stories.

By type of document, it is assumed that these documents will follow the same structure. For Example, a document model called `Epic` can expect to have a `# Title ` heading and a subheading `## Stories` that contains multiple `### Story Title` subheadings underneath it.

Each of these subheadings can eventually become the title of a separate `Story` document, which will relate to the parent `Epic` by e.g. its frontmatter metadata or the subfolder it lives in.

Models can automatically be associated with other Models through [Relationships](./models/relationships.mdx)

Given the MDX content in [epics/authentication.mdx](../../../examples/sdlc/epics/authentication.mdx)

```markdown
---
status: proposed
---

# Authentication

The Authentication stories cover users logging in and out of the application, as well as the roles and permissions granted to these users and how they are enforced in the application.

## Stories

### A User should be able to register

As a User I would like to register so that I can use the application.

### A User should be able to login

As a User I would like to login so that I can use the application.

### A User should be able to logout

As a User I would like to logout so that I can use the application.

### A User should be able to change their password

As a User I would like to change my password so that I can use the application.

### A User should be able to reset their password

As a User I would like to reset my password so that I can use the application.
```

The model can work with this content as data:

```javascript
const epic = collection.getModel("epics/authentication")
const json = epic.toJSON({ related: ["stories"] })

// results in
{
  "id": "epics/authentication",
  "meta": {
    "status": "proposed"
  },
  "title": "Authentication",
  "stories": [
    {
      "id": "stories/authentication/a-user-should-be-able-to-register",
      "meta": {
        "epic": "authentication"
      },
      "title": "A User Should be able to Register"
    },
    {
      "id": "stories/authentication/a-user-should-be-able-to-login",
      "meta": {
        "epic": "authentication"
      },
      "title": "A User should be able to login"
    },
    /*... omitted */
  ]
}
```

## Defining a Model Class

A Model class inherits from [Model](../../api/Model.mdx)

```javascript
// models/Epic.js
import { Model } from "active-mdx/model"

export default class Epic extends Model {
  stories() {
    return this.hasMany("Story", {
      heading: "stories"
    })
  }
}
```

And is registered with the collection

```javascript
// index.js
import { Collection } from "active-mdx/collection"
import Epic from "./models/Epic.js"

const collection = new Collection({
  models: [Epic]
})

// or
collection.model("Epic", Epic)
```

Following a convention over configuration approach, if you have a folder inside your collection called models with model classes in it, then these models will automatically be registered with the collection.

```javascript
collection.load({ models: true }).then((collection) => {
  collection.modelClasses // => [ Epic]
})
```

## Model -> Document Relationships

If you have a model class `Epic` there will be `Epic.inflections.plural == 'epics'` which will be the default `Model.prefix`.

Any `.mdx` files inside the folder `epics` will be automatically associated with the `Epic` model.

If you have an epic in another folder, you can specify the model through mdx frontmatter

```markdown
---
type: Epic
---

# My Epic Title
```

## Accessing a Model Instance through the collection

```javascript
collection.getModel("epics/authentication")
```
