Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

getAll request on '_MANY' association #191

Closed
clegirar opened this issue Aug 22, 2019 · 8 comments
Closed

getAll request on '_MANY' association #191

clegirar opened this issue Aug 22, 2019 · 8 comments

Comments

@clegirar
Copy link

Describe the bug
I want to get '_MANY' association and rest-hapi return all datas of the model of association

To Reproduce
Steps to reproduce the behavior:

  1. Create '_MANY' association
associations: {
	companies: {
		type: '_MANY',
		alias: 'companies',
		model: 'companies',
	},
},
  1. I am creating companies in the model companies

Capture d’écran 2019-08-22 à 18 07 04

  1. I post an id company in my companies association

Capture d’écran 2019-08-22 à 18 19 53

  1. I get the association companies and response contains all the companies whereas in the companies association i have only one company
{
  "docs": [
    {
      "_id": "5d5cae2e3356752c4f2d4414",
      "subsidiaries": [
        {
          "_id": "5d5cae373356752c4f2d4416",
          "subsidiaries": [],
          "name": "string",
          "naf": "string",
          "siret": "string",
          "createdBy": "5d5c9e1a6b233e246ad4f611",
          "createdAt": "2019-08-21T02:36:39.450Z",
          "institutions": []
        }
      ],
      "name": "string",
      "naf": "string",
      "siret": "string",
      "createdBy": "5d5c9e1a6b233e246ad4f611",
      "createdAt": "2019-08-21T02:36:30.548Z",
      "institutions": []
    },
    {
      "_id": "5d5cae373356752c4f2d4416",
      "subsidiaries": [],
      "name": "string",
      "naf": "string",
      "siret": "string",
      "createdBy": "5d5c9e1a6b233e246ad4f611",
      "createdAt": "2019-08-21T02:36:39.450Z",
      "institutions": []
    },
    {
      "_id": "5d5ebd0207b9b804f763dc2a",
      "subsidiaries": [],
      "name": "Hey",
      "naf": "string",
      "siret": "string",
      "createdBy": "5d5db71b1c99220acc90ae45",
      "createdAt": "2019-08-22T16:04:18.189Z",
      "institutions": []
    }
  ],
  "pages": {
    "current": 1,
    "prev": 0,
    "hasPrev": false,
    "next": 2,
    "hasNext": false,
    "total": null
  },
  "items": {
    "begin": null,
    "end": null,
    "total": 3
  }
}

Expected behavior
getAll request on '_MANY' association should return only the id's of the association and not fulld datas of the corresponding model.

Desktop (please complete the following information):

  • OS: OSX
  • Browser: Chrome
  • Version: 76.0.3809.100

Additional context
Sorry for my deplorable English, i hope its comprehensive ! Thanks for your answer.

@JKHeadley
Copy link
Owner

Hi @Clemssss, thanks for reaching out.

I believe I understand the issue you describe, though I will need some more information since I am unable to replicate it on my end.

  1. Is this response from a REST endpoint (i.e GET /<your entity>/{ownerId}/companies) or from a wrapper method?

  2. Could you display the JSON for the original parent object containing the _MANY relationship? (i.e. the result of GET /<your entity>/{_id})

Let's start from there and see if we can figure out what's going wrong. Thanks!

@clegirar
Copy link
Author

clegirar commented Aug 22, 2019

Thank @JKHeadley for your speedy response !

  1. Yes is the response from the REST endpoint GET /<your entity>/{ownerId}/companies

  2. This is the response of GET /<your entity>/{_id} (companies is the _MANY relationship and she is embed), in itself this endpoint (GET /<your entity>/{_id}) return the _MANY relationship but if an endpoint is created just for this it would make more sense no ?

{
  "_id": "5d5db71b1c99220acc90ae45",
  "companies": [
    {
      "_id": "5d5cae373356752c4f2d4416",
      "subsidiaries": [],
      "name": "string",
      "naf": "string",
      "siret": "string",
      "createdBy": "5d5c9e1a6b233e246ad4f611",
      "createdAt": "2019-08-21T02:36:39.450Z",
      "institutions": []
    }
  ],
  "email": "test@test.com",
  "password": "$2b$10$N4QlJTSrMfurtS3/U13bi.Dr0e2CxidEufFUrKT.PuEgY/DLFdaWW",
  "firstName": "string",
  "lastName": "string",
  "rights": {
    "user": true,
    "oppusUser": false
  },
  "createdAt": "2019-08-21T21:26:51.661Z"
}

Once again thanks very much for your time and your reply!
(PS: I would like to know what happened about this issue #149 ?)

@JKHeadley
Copy link
Owner

Hmm, yes GET /<your entity>/{ownerId}/companies should return the same documents as the embedded companies field. I'm not sure why it is not in your case. Would you be able to share some code (mainly model files) that will allow me to replicate the issue?

@clegirar
Copy link
Author

Sure.
UserSchema ()

const UserSchema = new Schema({
	firstName: { type: String, required: true },
	lastName: { type: String, required: true },
	phone: { type: String },
	email: { type: String, required: true, index: { unique: true } },
	password: { type: String, required: true },
	authyId: { type: String },
	companies: [{ type: Schema.Types.ObjectId, ref: 'company' }],
	rights: { type: Schema.Types.Mixed, default: {} },
	savedData: { type: Schema.Types.Mixed, default: {} },
});

module.exports = () => {
	UserSchema.statics = {
		collectionName: 'user',
		routeOptions: {
			associations: {
				companies: {
					type: '_MANY',
					alias: 'companies',
					model: 'company',
				},
			},
			find: {
				pre: (_id, query, request) => {
					const user = request.auth.credentials;
					if (!_id || user._id !== _id) {
						throw Boom.unauthorized('You are not authorized with this account.');
					}
					return {
						$embed: ['companies'],
					};
				},
			},
			list: {
				pre: (query, request) => {
					const user = request.auth.credentials;
					if (!user.rights.oppusUser) {
						throw Boom.unauthorized('You are not authorized with this account.');
					}
					return {
						$embed: ['companies'],
					};
				},
			},
		},
	};
	return UserSchema;
};

CompanySchema

const CompanySchema = new Schema({
	name: { type: String, required: true },
	naf: { type: String, required: true },
	siret: { type: String, required: true },
	institutions: [{
		name: { type: String },
		address: {
			city: { type: String },
			street: { type: String },
			complementary: { type: String },
			zipCode: { type: String },
		},
		numberOfEmployees: { type: Number },
	}],
	subsidiaries: [{ type: Schema.Types.ObjectId, ref: 'company' }],
});

module.exports = () => {
	CompanySchema.statics = {
		collectionName: 'company',
		routeOptions: {
			associations: {
				subsidiaries: {
					type: '_MANY',
					alias: 'subsidiaries',
					model: 'company',
				},
			},
			find: {
				pre: () => ({
					$embed: ['subsidiaries'],
				}),
			},
			list: {
				pre: () => ({
					$embed: ['subsidiaries'],
				}),
			},
		},
	};
	return CompanySchema;
};

@clegirar
Copy link
Author

Ohh, i find, its the find and list pre-middlewares in the CompanySchema.
If i delete it, it works, but i don't know why ...?

@JKHeadley
Copy link
Owner

Hi @Clemssss, it's because you are overriding the query parameter in the middleware function instead of modifying it. getAll internally uses the query parameter to filter the results based on the ownerId. When you override it, you erase the filter and therefore get all of the company documents rather than the docs under the ownerId.

Try changing your middleware to:

	find: {
	  pre: (_id, query, request, Log) => ({
            ...query,
            $embed: ['subsidiaries']
          }),
	},
	list: {
	  pre: (query, request, Log) => ({
            ...query,
            $embed: ['subsidiaries']
          }),
	},

@clegirar
Copy link
Author

Exactly, im stupid ... Thanks for your response !

@JKHeadley
Copy link
Owner

Not at all, its easy to miss!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants