Skip to content

Commit c52fdb2

Browse files
authored
refactor: association types (#187)
* 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
1 parent 330da19 commit c52fdb2

File tree

87 files changed

+1082
-852
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

87 files changed

+1082
-852
lines changed

Diff for: README.md

+40-22
Original file line numberDiff line numberDiff line change
@@ -97,10 +97,12 @@ EXAMPLES OF VALID JSON FILES
9797

9898
"associations" : {
9999
"person" : {
100-
"type" : "to_one",
100+
"type" : "many_to_one",
101+
"implementation": "foreignkeys",
102+
"reverseAssociation": "dogs",
101103
"target" : "Person",
102104
"targetKey" : "personId",
103-
"keyIn": "Dog",
105+
"keysIn": "Dog",
104106
"targetStorageType" : "sql"
105107
}
106108
}
@@ -119,10 +121,12 @@ EXAMPLES OF VALID JSON FILES
119121
},
120122
"associations":{
121123
"books" : {
122-
"type" : "to_many",
124+
"type" : "one_to_many",
125+
"implementation": "foreignkeys",
126+
"reverseAssociation": "publisher",
123127
"target" : "Book",
124128
"targetKey" : "publisherId",
125-
"keyIn" : "Book",
129+
"keysIn" : "Book",
126130
"targetStorageType" : "sql"
127131
}
128132
}
@@ -153,32 +157,38 @@ Example:
153157

154158
### Associations Spec
155159

156-
We will consider two types of associations accordingly to the number of records
157-
that can posibly be associated:
158-
1. to_one
159-
2. to_many
160+
We will consider four types of associations according to the relation between associated records of the two models:
161+
1. one_to_one
162+
2. many_to_one
163+
3. one_to_many
164+
4. many_to_many
160165

161-
For both type of association, the necessary arguments would be:
166+
For all types of association, the necessary arguments would be:
162167

163168
name | Type | Description
164169
------- | ------- | --------------
165-
*type* | String | Type of association (like belongsTo, etc.)
170+
*type* | String | Type of association (`one_to_one`, `one_to_many`, etc.)
171+
*implementation* | String | implementation type of the association. Can be one of `foreignkeys`, `generic` or `sql_cross_table` (only for `many_to_many`)`
172+
*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.
166173
*target* | String | Name of model to which the current model will be associated with.
167174
*targetKey* | String | A unique identifier of the association for the case where there appear more than one association with the same model.
168-
*keyIn* | String | Name of the model where the targetKey is stored.
175+
*keysIn* | String | Name of the model where the targetKey is stored.
169176
*targetStorageType* | String | Type of storage where the target model is stored. So far can be one of __sql__ or __Webservice__.
170177
*label* | String | Name of the column in the target model to be used as a display name in the GUI.
171178
*sublabel* | String | Optional name of the column in the target model to be used as a sub-label in the GUI.
172179

173-
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:
180+
**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.
181+
182+
When the association is of type *many_to_many* it's necessary to describe an extra argument *sourceKey*:
174183

175184
name | Type | Description
176185
------- | ------- | --------------
177186
*sourceKey* | String | Key to identify the source id
178-
*keysIn* | String | Name of the cross table
187+
188+
Be aware that in case of a *many_to_many* via an *sql_cross_table* implementation the keysIn field points to the cross model.
179189

180190
## NOTE:
181-
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:
191+
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:
182192

183193
```jsonc
184194
//User model
@@ -191,7 +201,9 @@ Be aware that in the case of this type of association the user is required to de
191201
},
192202
"associations" :{
193203
"roles" : {
194-
"type" : "to_many",
204+
"type" : "many_to_many",
205+
"implementation": "foreignkeys",
206+
"reverseAssociation": "dogs",
195207
"target" : "Role",
196208
"targetKey" : "role_Id",
197209
"sourceKey" : "user_Id",
@@ -215,8 +227,10 @@ Be aware that in the case of this type of association the user is required to de
215227
},
216228
"associations" : {
217229
"users" : {
218-
"type" : "to_many",
230+
"type" : "many_to_many",
219231
"target" : "User",
232+
"implementation": "sql_cross_table",
233+
"reverseAssociation": "roles",
220234
"targetKey" : "user_Id",
221235
"sourceKey" : "role_Id",
222236
"keysIn" : "role_to_user",
@@ -254,11 +268,13 @@ Example:
254268
},
255269
"associations":{
256270
"publisher" : {
257-
"type" : "to_one", // association type
271+
"type" : "many_to_one", // association type
272+
"implementation": "foreignkeys", // standard implementation via foreign keys
273+
"reverseAssociation": "dogs", // name of the association in the publisher model
258274
"target" : "publisher", // Model's name is `publisher`
259275
"targetKey" : "publisher_id", // Local alias for this association
260-
"keyIn": "book", // FK to publisher will be stored in the Book model
261-
"targetStorageType" : Webservice", // It's a remote database
276+
"keysIn": "book", // FK to publisher will be stored in the Book model
277+
"targetStorageType" : "Webservice", // It's a remote database
262278
"label" : "name" // Show in GUI the name of the publisher taken from external DB
263279
}
264280
}
@@ -276,13 +292,15 @@ Example:
276292
"model" : "Book",
277293
"storageType" : "SQL",
278294
"attributes" : {
279-
"id" : Int,
295+
"id" : "Int",
280296
"title" : {"type":"String", "description": "The book's title"},
281-
"ISBN": Int
297+
"ISBN": "Int"
282298
},
283299
"associations" : {
284300
"authors" : {
285-
"type" : "to_many",
301+
"type" : "many_to_many",
302+
"implementation": "sql_cross_table",
303+
"reverseAssociation": "books",
286304
"target" : "Person",
287305
"targetKey" : "person_id",
288306
"sourceKey" : "book_id",

0 commit comments

Comments
 (0)