Skip to content

Commit

Permalink
refactor: association types (#187)
Browse files Browse the repository at this point in the history
* refactor: association types to be either:
- one_to_one
- one_to_many
- many_to_one
- many_to_many
refactor: add "implementation" field to the association definition to be on of:
- sql_cross_table
- generic
- foreignkey

* refactor: unit tests for new association types

* refactor: new association types for integration test models

* fix: add missing implementation types

* refactor: add "reverseAssociation" field to association definition

* fix: unit tests - add reverseAssociation

* refactor: update README for new association types

* refactor: remove check for targetStorageType on sql_cross_table implementation

* refactor: always use "keysIn" instead of "keyIn" / "keysIn"

* refactor: update README for keysIn

* refactor: rename assoc field "foreignkey" -> "foreignkeys"

* Merge branch 'master' into refactor-assoc-types

* fix: non generic models always have "keysIn"

* fix: missing "to_one" in README

* fix: neo4j test models to new assoc types

* fix: unit tests

* chore: remove console.log

* fix: README many_to_many example assoc type
  • Loading branch information
coeit authored Jun 17, 2021
1 parent 330da19 commit c52fdb2
Show file tree
Hide file tree
Showing 87 changed files with 1,082 additions and 852 deletions.
62 changes: 40 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,12 @@ EXAMPLES OF VALID JSON FILES

"associations" : {
"person" : {
"type" : "to_one",
"type" : "many_to_one",
"implementation": "foreignkeys",
"reverseAssociation": "dogs",
"target" : "Person",
"targetKey" : "personId",
"keyIn": "Dog",
"keysIn": "Dog",
"targetStorageType" : "sql"
}
}
Expand All @@ -119,10 +121,12 @@ EXAMPLES OF VALID JSON FILES
},
"associations":{
"books" : {
"type" : "to_many",
"type" : "one_to_many",
"implementation": "foreignkeys",
"reverseAssociation": "publisher",
"target" : "Book",
"targetKey" : "publisherId",
"keyIn" : "Book",
"keysIn" : "Book",
"targetStorageType" : "sql"
}
}
Expand Down Expand Up @@ -153,32 +157,38 @@ Example:

### Associations Spec

We will consider two types of associations accordingly to the number of records
that can posibly be associated:
1. to_one
2. to_many
We will consider four types of associations according to the relation between associated records of the two models:
1. one_to_one
2. many_to_one
3. one_to_many
4. many_to_many

For both type of association, the necessary arguments would be:
For all types of association, the necessary arguments would be:

name | Type | Description
------- | ------- | --------------
*type* | String | Type of association (like belongsTo, etc.)
*type* | String | Type of association (`one_to_one`, `one_to_many`, etc.)
*implementation* | String | implementation type of the association. Can be one of `foreignkeys`, `generic` or `sql_cross_table` (only for `many_to_many`)`
*reverseAssociation* | String | The name of the reverse association from the other model. This field is only mandatory for building the [single-page-app](https://github.com/Zendro-dev/single-page-app), *not* for generating the the graphql-server code via this repository.
*target* | String | Name of model to which the current model will be associated with.
*targetKey* | String | A unique identifier of the association for the case where there appear more than one association with the same model.
*keyIn* | String | Name of the model where the targetKey is stored.
*keysIn* | String | Name of the model where the targetKey is stored.
*targetStorageType* | String | Type of storage where the target model is stored. So far can be one of __sql__ or __Webservice__.
*label* | String | Name of the column in the target model to be used as a display name in the GUI.
*sublabel* | String | Optional name of the column in the target model to be used as a sub-label in the GUI.

When the association is of type *to_many* and it referes to a more particular type of association *many_to_many* it's necessary to describe two extra arguments given that the association is made with a cross table. These arguments are:
**Note**: The `keysIn` argument points to the model that stores the information about the foreignKey(s). That can be either a single key, a foreignkey array or a cross-model.

When the association is of type *many_to_many* it's necessary to describe an extra argument *sourceKey*:

name | Type | Description
------- | ------- | --------------
*sourceKey* | String | Key to identify the source id
*keysIn* | String | Name of the cross table

Be aware that in case of a *many_to_many* via an *sql_cross_table* implementation the keysIn field points to the cross model.

## NOTE:
Be aware that in the case of this type of association the user is required to describe the cross table used in the field _keysIn_ as a model in its own. For example, if we have a model `User` and a model `Role` and they are associated in a _manytomany_ way, then we also need to describe the `role_to_user` model:
Be aware that in the case of this type of association the user is required to describe the cross table used in the field _keysIn_ as a model in its own. For example, if we have a model `User` and a model `Role` and they are associated in a `many_to_many` way, then we also need to describe the `role_to_user` model:

```jsonc
//User model
Expand All @@ -191,7 +201,9 @@ Be aware that in the case of this type of association the user is required to de
},
"associations" :{
"roles" : {
"type" : "to_many",
"type" : "many_to_many",
"implementation": "foreignkeys",
"reverseAssociation": "dogs",
"target" : "Role",
"targetKey" : "role_Id",
"sourceKey" : "user_Id",
Expand All @@ -215,8 +227,10 @@ Be aware that in the case of this type of association the user is required to de
},
"associations" : {
"users" : {
"type" : "to_many",
"type" : "many_to_many",
"target" : "User",
"implementation": "sql_cross_table",
"reverseAssociation": "roles",
"targetKey" : "user_Id",
"sourceKey" : "role_Id",
"keysIn" : "role_to_user",
Expand Down Expand Up @@ -254,11 +268,13 @@ Example:
},
"associations":{
"publisher" : {
"type" : "to_one", // association type
"type" : "many_to_one", // association type
"implementation": "foreignkeys", // standard implementation via foreign keys
"reverseAssociation": "dogs", // name of the association in the publisher model
"target" : "publisher", // Model's name is `publisher`
"targetKey" : "publisher_id", // Local alias for this association
"keyIn": "book", // FK to publisher will be stored in the Book model
"targetStorageType" : Webservice", // It's a remote database
"keysIn": "book", // FK to publisher will be stored in the Book model
"targetStorageType" : "Webservice", // It's a remote database
"label" : "name" // Show in GUI the name of the publisher taken from external DB
}
}
Expand All @@ -276,13 +292,15 @@ Example:
"model" : "Book",
"storageType" : "SQL",
"attributes" : {
"id" : Int,
"id" : "Int",
"title" : {"type":"String", "description": "The book's title"},
"ISBN": Int
"ISBN": "Int"
},
"associations" : {
"authors" : {
"type" : "to_many",
"type" : "many_to_many",
"implementation": "sql_cross_table",
"reverseAssociation": "books",
"target" : "Person",
"targetKey" : "person_id",
"sourceKey" : "book_id",
Expand Down
Loading

0 comments on commit c52fdb2

Please sign in to comment.