You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
92 lines
2.7 KiB
92 lines
2.7 KiB
3 years ago
|
## The AdminJS Data model
|
||
|
|
||
|
Before you dive into the details of the flat helpers, let me briefly introduce the way how the
|
||
|
database data is stored in AdminJS.
|
||
|
|
||
|
### The Simple Case
|
||
|
|
||
|
On the backend all the information from DataBase tables/collections goes to {@BaseRecord#params}
|
||
|
object. Usually, it is a `{key: value}` store where `key` is a table name, and value could be
|
||
|
either a string, a number, or an instance of Date() etc.
|
||
|
|
||
|
On the Frontend - these values go to the corresponding {@link RecordJSON.params} property.
|
||
|
|
||
|
This is an example `params` property in the "simple case":
|
||
|
|
||
|
```javascript
|
||
|
params: {
|
||
|
name: 'John',
|
||
|
surname: 'Doe',
|
||
|
age: 28,
|
||
|
}
|
||
|
```
|
||
|
|
||
|
### The Real World Case
|
||
|
|
||
|
In the real world:
|
||
|
* databases have nested JSONB properties or Mixed Schemas
|
||
|
* developers would like to send more complicated data from the Fronted to the backend as arrays.
|
||
|
|
||
|
To achieve that we "flatten" all the data before saving them to `params` property.
|
||
|
|
||
|
So in the real world params could look like:
|
||
|
|
||
|
```javascript
|
||
|
params: {
|
||
|
name: 'John',
|
||
|
surname: 'Doe',
|
||
|
age: 28,
|
||
|
// nested objects
|
||
|
'auth.facebook': 'some login token',
|
||
|
'auth.twitter': 'twitter login token',
|
||
|
// arrays
|
||
|
'interests.0': 'running',
|
||
|
'interests.1': 'jogging',
|
||
|
}
|
||
|
```
|
||
|
and all the data can be even nested on the deeper levels.
|
||
|
|
||
|
### Why we did that?
|
||
|
|
||
|
An alternative solution would be to store an entire raw object and don't care. But there are 2
|
||
|
reasons why we picked this one.
|
||
|
|
||
|
**1. storing selected data in the database**
|
||
|
|
||
|
If you send to the ORM unflatten save request like this:
|
||
|
|
||
|
```javascript
|
||
|
Model.save({{ auth: { facebook: 'newFacebookToken' } }})
|
||
|
```
|
||
|
|
||
|
it will override an entire `auth` property, so from the example above, we will lose `auth.twitter`.
|
||
|
|
||
|
In the second (flatten) case:
|
||
|
|
||
|
```javascript
|
||
|
Model.save({ `auth.facebook`: 'newFacebookToken' }})
|
||
|
```
|
||
|
|
||
|
ORM should keep the value of the `auth.twitter`
|
||
|
|
||
|
> The above is true for Mongoose adapter which is the most advanced regarding handing mixed values
|
||
|
|
||
|
**2. Sending data between the Frontend and the Backend in {@link https://developer.mozilla.org/en-US/docs/Web/API/FormData FormData} format**
|
||
|
|
||
|
AdminJS allows you to upload Files from the Frontend to the Backend. The most optimal way of
|
||
|
doing that is by using {@link https://developer.mozilla.org/en-US/docs/Web/API/FormData FormData}.
|
||
|
But, this requires that values for all the fields are send in `[key: string]: string` form.
|
||
|
And this, as you might guess, fits perfectly to our flatten `params` logic.
|
||
|
|
||
|
### Consequences
|
||
|
|
||
|
Flattening in AdminJS has its consequences everywhere where you use
|
||
|
|
||
|
- {@link BaseRecord} and
|
||
|
- {@link RecordJSON},
|
||
|
|
||
|
because instead of raw object you have it's flatten version.
|
||
|
|
||
|
Also, (as mentioned) the `payload` send to the backed is also flattened.
|
||
|
|
||
|
There you should use helpers gathered in {@link flat}
|