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

feat(repository): delete & patch operations for HasOne relation #2414

Merged
merged 1 commit into from
Mar 21, 2019

Conversation

RaphaelDrai
Copy link

@RaphaelDrai RaphaelDrai commented Feb 17, 2019

implemented the missing crud operations delete, patch and put operations
in relation hasOne.

"fix #2233"

Checklist

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

Copy link
Contributor

@elv1s elv1s left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My comments are mainly around handling primary keys. Thanks @RaphaelDrai

packages/repository/src/model.ts Outdated Show resolved Hide resolved
packages/repository/src/model.ts Outdated Show resolved Hide resolved
Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great start!

I am proposing to remove the PUT endpoint from this pull request, it requires more discussion and non-trivial implementation.

@bajtos bajtos added feature Relations Model relations (has many, etc.) labels Mar 5, 2019
Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice progress!

@bajtos bajtos changed the title feat(repository): implemented crud operations in hasone relation feat(repository): delete & patch operations for HasOne relation Mar 12, 2019
@bajtos
Copy link
Member

bajtos commented Mar 14, 2019

Actually, the hasOne relation allows to create two targets for a same source. This is what I wrote in my previous comments. In my opinion, delete operation shall remove all targets associated to a same source. When we will fix this issue to avoid to create two targets for a same source (new PR) then we can remove the Where as you recommend.
What do you think, can we keep the where till the fix?

We were discussing referential integrity for relations in #2127, with two conclusions:

Now if you are using HasOne with PostgreSQL (or any other SQL database), then we require you to configure FOREIGN KEY and UNIQUE constraints to enforce HasOne constraints.

In my opinion, delete operation shall remove all targets associated to a same source.

I guess this makes sense. However, I don't understand how is the where parameter need for that? How do you envision its usage? IMO, we should simple delete all target models belonging to the source model instance.

When we will fix this issue to avoid to create two targets for a same source (new PR) then we can remove the Where as you recommend.

This won't be really fixed in LoopBack. We want to improve our auto-migration to automatically define SQL constraints as needed by relations (see #2332), and also improve our memory connector to enforce such constraints too (see #2333), but I am not sure if that can be considered as a fix?

const targetRepository = await this.getTargetRepository();
return await targetRepository.updateAll(
constrainDataObject(dataObject, this.constraint),
constrainWhere({}, this.constraint as Where<TargetEntity>),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly here, why is the explicit cast to Where<TargetEntity> needed? Can we find a way that would not require it?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RaphaelDrai PTAL, can we remove this explicit type cast here?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to call constrainWhere at all? I think we can use this.constraint directly.

Suggested change
constrainWhere({}, this.constraint as Where<TargetEntity>),
this.constraint,

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The patch looks mostly good now. I'd like to see two changes before we land it:

  • Remove the where argument from delete method.
  • Check if we can remove as Were<TargetEntity> cast, it looks like a code smell to me.

import { Getter } from '@loopback/context';
import { DataObject, Options, Count } from '../../common-types';
import { Entity } from '../../model';
import { Filter, Where } from '../../query';
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't add spaces around braces, please run npm run lint:fix.

const targetRepository = await this.getTargetRepository();
return await targetRepository.updateAll(
constrainDataObject(dataObject, this.constraint),
constrainWhere({}, this.constraint as Where<TargetEntity>),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@RaphaelDrai PTAL, can we remove this explicit type cast here?

@@ -87,4 +103,19 @@ export class DefaultHasOneRepository<
}
return found[0];
}
async delete(options?: Options): Promise<Count> {
const targetRepository = await this.getTargetRepository();
return targetRepository.deleteAll(options);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will delete ALL target model instances, not only the instance associated with the source model instance.

Please add a test to verify that delete preserves instances that are not related to the source model and then fix the implementation.

I think this is something we should verify for the PATCH operation too. Please add another test to check that PATCH is updating only the single instance on the other end of the relation.

Yet another two tests to consider: what happens when there is no target model instance? IMO, both delete and patch should run successfully and return {count: 0}.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
I did what you requested to remove the where argument etc... Note that I implemented hasOne same as hasMany is implemented and in hasMany there is no any test to verify the associated target model, the relation already handle it. Please see how hasMany is implement. If your assumption is right the same issue is existing in hasMany. But, when I made tests in hasOne with my initial code including PUT, hasOne worked as expected.
Just to keep you informed, someone else will continue the updates of hasOne with you.
I am moving to other responsibilities.
Kind regards
Raphael

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am afraid we misunderstood each other. I was asking to remove where argument from the public API, not from the underlying implementation...

Just to keep you informed, someone else will continue the updates of hasOne with you.
I am moving to other responsibilities.

Thank you for the update, I wish you good luck on your new assignment 🍀

@bajtos
Copy link
Member

bajtos commented Mar 19, 2019

To speed up landing of this pull request, I made the remaining changes myself in 1e199e8.

@raymondfeng @b-admike LGTY?

@bajtos bajtos requested a review from elv1s March 19, 2019 13:49
@bajtos bajtos self-assigned this Mar 19, 2019
Copy link
Contributor

@elv1s elv1s left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@bajtos bajtos merged commit 5936fb9 into loopbackio:master Mar 21, 2019
@bajtos
Copy link
Member

bajtos commented Mar 21, 2019

Landed, thank you for the contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Relations Model relations (has many, etc.)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

hasOne relation DELETE, PATCH and PUT CRUD operations are missing
4 participants