Fix(crud) include param lookup now works w/plurals
Previously, {one,many}-to-many relationships with models would result in
`associationNames` that were plural. e.g. `Team` might have many
players and one location. The validation was expecting to see the plural
`Players` and the singular `Location` but Sequelize is expecting the
singular `Player` (`Location` worked fine). This meant that include
lookups would silently fail. This fixes the problem in a backward-
compatible way.
It continues to allow `include=Location` (capitalized) for backward-
compatibility. And now allows and actually does the lookup for
`include=players`, `include=player`, `include=Player`, `include=Players`
lookup relationships.
			
			
This commit is contained in:
		
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
								
							| @@ -109,7 +109,7 @@ Getting related models is easy, just use a query parameter `include`. | ||||
|  | ||||
| ```js | ||||
| // returns all teams with their related City model | ||||
| // GET /teams?include=City | ||||
| // GET /teams?include=city | ||||
|  | ||||
| // results in a Sequelize query: | ||||
| Team.findAll({include: City}) | ||||
| @@ -118,12 +118,21 @@ Team.findAll({include: City}) | ||||
| If you want to get multiple related models, just pass multiple `include` parameters. | ||||
| ```js | ||||
| // returns all teams with their related City and Uniform models | ||||
| // GET /teams?include=City&include=Uniform | ||||
| // GET /teams?include[]=city&include[]=uniform | ||||
|  | ||||
| // results in a Sequelize query: | ||||
| Team.findAll({include: [City, Uniform]}) | ||||
| ``` | ||||
|  | ||||
| For models that have a many-to-many relationship, you can also pass the plural version of the association. | ||||
| ```js | ||||
| // returns all teams with their related City and Uniform models | ||||
| // GET /teams?include=players | ||||
|  | ||||
| // results in a Sequelize query: | ||||
| Team.findAll({include: [Player]}) | ||||
| ``` | ||||
|  | ||||
| ## `limit` and `offset` queries | ||||
| Restricting list (`GET`) and scope queries to a restricted count can be done by passing `limit=<number>` and/or `offset=<number>`. | ||||
|  | ||||
|   | ||||
							
								
								
									
										10
									
								
								src/crud.js
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								src/crud.js
									
									
									
									
									
								
							| @@ -55,7 +55,15 @@ models: { | ||||
| export default (server, model, { prefix, defaultConfig: config, models: permissions }) => { | ||||
|   const modelName = model._singular; | ||||
|   const modelAttributes = Object.keys(model.attributes); | ||||
|   const modelAssociations = Object.keys(model.associations); | ||||
|   const associatedModelNames = Object.keys(model.associations); | ||||
|   const modelAssociations = [ | ||||
|     ...associatedModelNames, | ||||
|     ..._.flatMap(associatedModelNames, (associationName) => { | ||||
|       const { target } = model.associations[associationName]; | ||||
|       const { _singular, _plural, _Singular, _Plural } = target; | ||||
|       return [_singular, _plural, _Singular, _Plural]; | ||||
|     }), | ||||
|   ]; | ||||
|  | ||||
|   const attributeValidation = modelAttributes.reduce((params, attribute) => { | ||||
|     params[attribute] = joi.any(); | ||||
|   | ||||
| @@ -32,6 +32,8 @@ const register = (server, options = {}, next) => { | ||||
|     const { plural, singular } = model.options.name; | ||||
|     model._plural = plural.toLowerCase(); | ||||
|     model._singular = singular.toLowerCase(); | ||||
|     model._Plural = plural; | ||||
|     model._Singular = singular; | ||||
|  | ||||
|     // Join tables | ||||
|     if (model.options.name.singular !== model.name) continue; | ||||
|   | ||||
| @@ -20,6 +20,13 @@ export const parseInclude = request => { | ||||
|   const { models } = noGetDb ? request : request.getDb(); | ||||
|  | ||||
|   return include.map(a => { | ||||
|     const singluarOrPluralMatch = Object.keys(models).find((modelName) => { | ||||
|       const { _singular, _plural } = models[modelName]; | ||||
|       return _singular === a || _plural === a; | ||||
|     }); | ||||
|  | ||||
|     if (singluarOrPluralMatch) return models[singluarOrPluralMatch]; | ||||
|  | ||||
|     if (typeof a === 'string') return models[a]; | ||||
|  | ||||
|     if (a && typeof a.model === 'string' && a.model.length) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user