> Note: If you are just starting out it is very convenient to generate some models with the Content Type Builder, directly in the admin interface. You can then review the generated model mappings on the code level. The UI takes over a lot of validation tasks and gives you a fast feeling for available features.
Use the CLI, and run the following command `strapi generate:model user firstname:string lastname:string`. Read the [CLI documentation](../cli/CLI.md) for more informations.
This will create two files located at `./api/user/models`:
You can apply basic validations to the attributes. The following supported validations are *only supported by MongoDB* connection.
If you're using SQL databases, you should use the native SQL constraints to apply them.
-`required` (boolean) — if true adds a required validator for this property.
-`unique` (boolean) — whether to define a unique index on this property.
-`max` (integer) — checks if the value is greater than or equal to the given minimum.
-`min` (integer) — checks if the value is less than or equal to the given maximum.
**Security validations**
To improve the Developer eXperience when developing or using the administration panel, the framework enhances the attributes with these "security validations":
-`private` (boolean) — if true, the attribute will be removed from the server response (it's useful to hide sensitive data).
-`configurable` (boolean) - if false, the attribute isn't configurable from the Content Type Builder plugin.
> Note: The `dominant` key allows you to define in which table/collection (only for NoSQL databases) should be stored the array that defines the relationship. Because there is no join table in NoSQL, this key is required for NoSQL databases (ex: MongoDB).
Refer to the [polymorphic concept](../concepts/concepts.md#polymorphic) for more informations.
The polymorphic relationships are the solution when you don't know which kind of model will be associated to your entry. A common use case is an `Image` model that can be associated to many others kind of models (Article, Product, User, etc).
#### Single vs Many
Let's stay with our `Image` model which might belongs to **a single `Article` or `Product` entry**.
> In other words, it means that a `Image` entry can be associated to one entry. This entry can be a `Article` or `Product` entry.
The `filter` attribute is optional (but we highly recommend to use every time). If it's provided it adds a new match level to retrieve the related data.
For example, the `Product` model might have two attributes which are associated to the `Image` model. To distinguish which image is attached to the `cover` field and which images are attached to the `pictures` field, we need to save and provide this to the database.
If you're using MongoDB as a database, you don't need to do anything. Everything is natively handled by Strapi. However, to implement a polymorphic relationship with SQL databases, you need to create two tables.
The first table to create is the table which has the same name as your model.
```
CREATE TABLE `image` (
`id` int(11) NOT NULL,
`name` text NOT NULL,
`text` text NOT NULL
)
```
> Note: If you've overrided the default table name given by Strapi by using the `collectionName` attribute. Use the value set in the `collectionName` to name the table.
The second table will allow us to associate one or many others entries to the `Image` model. The name of the table is the same as the previous one with the suffix `_morph`.
```
CREATE TABLE `image_morph` (
`id` int(11) NOT NULL,
`image_id` int(11) NOT NULL,
`related_id` int(11) NOT NULL,
`related_type` text NOT NULL,
`field` text NOT NULL
)
```
-`image_id` is using the name of the first table with the suffix `_id`.
- **Attempted value:** It correspond to the id of an `Image` entry.
-`related_id` is using the attribute name where the relation happens with the suffix `_id`.
- **Attempted value:** It correspond to the id of an `Article` or `Product` entry.
-`related_type` is using the attribute name where the relation happens with the suffix `_type`.
- **Attempted value:** It correspond to the table name where the `Article` or `Product` entry is stored.
-`field` is using the filter property value defined in the model. If you change the filter value, you have to change the name of this column as well.
- **Attempted value:** It correspond to the attribute of a `Article`, `Product` with which the `Image` entry is related.
| id | image_id | related_id | related_type | field |
Each of these functions receives a parameter called `next`, which is the callback you should call after your logic is executed. The entry is accessible through `this`.
In this example, the model `User` will be accessible through the `Users` global variable. The data will be stored in the `Users_v1` collection or table and the model will use the `mongo` connection defined in `./config/environments/**/database.json`
> Note: The `connection` value can be changed whenever you want, but you should be aware that there is no automatic data migration process. Also if the new connection doesn't use the same ORM you will have to rewrite your queries.