Initially I thought that we will have to add special checks to allow relationships referencing itself. However, it turned out that not to be the case. Instead, it had more to do with how self relationships are defined in Mikro ORM.
In case of `belongsTo` relationship we have to define the other side as well either as a `hasMany` or `hasOne`. For example:
**❌ The following code will fail, because no children are defined for the parent**
```ts
const user = model.define("user", {
id: model.number(),
username: model.text(),
parent: model.belongsTo(() => user)
})
```
**✅ Addition of children relationship will make things work**
```ts
const user = model.define("user", {
id: model.number(),
username: model.text(),
parent: model.belongsTo(() => user, { mappedBy: "children" }),
children: model.hasMany(() => user, { mappedBy: "parent" }),
})
```
We can see the similar setup here with our `ProductCategory` MikroORM entity. https://github.com/medusajs/medusa/blob/develop/packages/modules/product/src/models/product-category.ts#L87-L94
@adrien2p Correct me if I am wrong. But I have added the tests for now so that we know the behavior of self relationships
**What**
Currently, when setting a `belongsTo` relationship on the DML with the otherside being `hasMany` it result in a wrongly generated gql output making the belongs to being a collection of the relation instead of the relation directly. This pr fixes this issue
**What**
When both sides of a many to many relationship do not define the mapped by option, it leads to misconfigured relations and a malformed SQL query. (ref. https://github.com/medusajs/medusa/issues/9075)
- When both mapped by are not defined, infer look up to try to identify the missing configuration if any
- Disallow defining many to many only on one side
FIXES FRMW-2676
**What**
ref: https://discord.com/channels/876835651130097704/1023889804544458752/threads/1276979858781503528
Currently, when providing the following
```ts
const user1 = manager.create(User, {
username: "User 1",
team: {
name: "Team 1",
},
})
```
It would result in an error inserting into the database because the foreign key will be sent twice as part of the insert, one for the relation and one for the foreign key that both relate to the foreign key property.
To fix that and allow both approaches (providing the entity to cascade persist or just providing the foreign key in case of another side nullable relation) we need to handle it a bit differently.
now both approaches would be valid. the entities for the example might not be the best ones but it is just to illustrate
option 1 - we create both the user and the team:
```ts
const user1 = manager.create(User, {
username: "User 1",
team: {
name: "Team 1",
},
})
```
option 2 - the team already exists (for example the previous user have been detached from the team but we kept the team alive and assign a new user to that team) :
```ts
const user1 = manager.create(User, {
username: "User 1",
team_id: team.id
})
```
**what:**
- DML can apply composite indexes
- Where clause is currently a string, QB version will come as a follow up
```
model.define("user", {
email: model.text(),
account: model.text(),
}).indexes([
{
name: "IDX-unique-name",
unique: true,
on: ["email", "account"],
where: "email is NOT NULL",
},
])
```
RESOLVES CORE-2391
* chore: various DML improvements
* Check is something through static utils
* Check is something through static utils
* allow to define a schema with table name
* restrict searchable to text only
* rm searchable modifier
* extract constructor logic into separate function