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

Polymorphic relation type #2487

Closed
bajtos opened this issue Feb 26, 2019 · 15 comments
Closed

Polymorphic relation type #2487

bajtos opened this issue Feb 26, 2019 · 15 comments
Assignees
Labels
feature parity feature Relations Model relations (has many, etc.)

Comments

@bajtos
Copy link
Member

bajtos commented Feb 26, 2019

Support polymorphic relation type.

For example, as single AccessToken model class can belong to multiple user-like model classes, using AccessToken's principalType property to distinguish between the targets.

See also LB 3.x docs: https://loopback.io/doc/en/lb3/Polymorphic-relations.html

@bajtos bajtos added feature Relations Model relations (has many, etc.) feature parity 2019Q2 labels Feb 26, 2019
@bajtos bajtos changed the title Polymorphic relation Polymorphic relation type Feb 26, 2019
@dhmlau
Copy link
Member

dhmlau commented Feb 26, 2019

cc @aharbis
I think this is something you're looking for.

@aharbis
Copy link
Contributor

aharbis commented Feb 26, 2019

Thanks @dhmlau! Yes, this is a huge feature for our use-case. I'm happy to assist in design / testing / contributing where I can.

@hanut
Copy link

hanut commented Apr 13, 2020

Is this being actively pursued or is contribution welcome ?
Also, is there any interim solution while a long term implementation is built.

@dhmlau
Copy link
Member

dhmlau commented Apr 16, 2020

@hanut, it's not being actively pursued but contribution is always welcome.

Also, is there any interim solution while a long term implementation is built.

@bajtos might be able to shed some light on this.

cc @hacksparrow

@hanut
Copy link

hanut commented Apr 16, 2020

@bajtos @dhmlau
In that case would it be okay if I pick it up to solve ?
My current project requires it urgently and seeing as I have been in love with Loopback since lb2, I really don't want to use anything else.

@dhmlau
Copy link
Member

dhmlau commented Apr 16, 2020

In that case would it be okay if I pick it up to solve ?

Absolutely! Let me assign it to you then. Thank you!

@bajtos
Copy link
Member Author

bajtos commented Apr 16, 2020

Hi @hanut, thank you for picking up this task! Please let us know if you need any help, the fastest option is to reach out in #loopback-contributors channel in our Slack (invite: https://join.slack.com/t/loopbackio/shared_invite/zt-8lbow73r-SKAKz61Vdao~_rGf91pcsw).

Adding a new relation type usually involves a lot of design decisions to be made and many lines of code. It's best to open a draft pull request as early as you have something to show. This way we can discuss the right direction early on and avoid extensive rework (and wasted efforts) later on.

Good luck! 🍀 I am looking forward to see you proposal. ✌️

@hanut
Copy link

hanut commented Apr 17, 2020

@bajtos @dhmlau
Cool. Im going to get started on this asap.

@hanut
Copy link

hanut commented Apr 26, 2020

I have been working on an implementation and am stuck with a few considerations -

  1. Polymorphic relations are basically just hasOne/hasMany <-> belongsTo relations with extra steps ie. adding in the type field to specify which type of related model is being referenced. However including the related data involves performing joins/lookups on the different tables/collections that are being referenced so I have a couple of performance concerns.
  2. What level would this relation target ? I mean, for mongo (via the mongo connector) it would require $lookups and for sql it would need joins. Or should the inclusion happen at the db level (via query) or within the application layer (possibly using multiple queries).
  3. The relations can also be established by adding multiple attributes for the fk of each entity type and only filling the one that is used. This shifts the operational complexity at framework layer to the database layer. (Joining the primary table with as many tables as there are foreignKey types)

For my use case, I implemented polymorphic relations using simple hasMany <-> belongsTo relations, one for each type of the morphable type. It works fine but at the expense of having nulls in the database.

I would like to get your view on this as I am pretty stuck with how to move forward with it.

@dhmlau
Copy link
Member

dhmlau commented May 6, 2020

For prosperity, I'm cross posting the reply from @bajtos on Slack:

Hi Hanut, I agree that in an ideal ORM, we would use SQL joins and MongoDB $lookups to perform the joins. We haven't implemented that in LoopBack so far, because it's non-trivial to support all different databases. Instead, we perform such queries in two steps:

  1. Query the source models to obtain a list of PK/FK values.
  2. Query the target models using IN (inq) operator to find all models matching the PK/FK values obtained in the step 1.

This seems to be working reasonably well, plus it allows you to have relations across databases (e.g. Users stored in legacy system-of-record SQL database can have "hasMany" relation to Sessions stored in MongoDB used by the front edge).
To implement a polymorphic relation, you should follow the current design and find a place where to inject your new logic that will decide which models (SQL tables) to query depending on the discriminator value.
You can take a look at the current implementation in juggler for inspiration.

@marcostoduto
Copy link

Are there any news related to this topic? I really need to implement this relation ASAP

@hanut
Copy link

hanut commented Aug 22, 2020

I did work on this for a while but shifted to using mongoose as the ODM while keep lb4 as the middleware layer.
Request @bajtos @dhmlau to reassign this to you in case you wish to take it up.

@GwendalBroudin
Copy link

Hi any progress on this topic?

@stale stale bot added the stale label Sep 25, 2021
@achrinza achrinza removed the stale label Sep 26, 2021
@loopbackio loopbackio deleted a comment from stale bot Sep 26, 2021
achrinza pushed a commit that referenced this issue Apr 3, 2022
Addressing the feature parity of polymorphic relations from lb3, and the syntax is similar to lb3.
The changes are backward compatible with previous apis. hasOne, belongsTo, and hasManyThrough
relations are supported, while hasMany relation can only facilitate this feature with an additional
one-on-one relation. Related to #2487

Signed-off-by: David Zhang <[email protected]>
@OnTheThirdDay
Copy link
Contributor

This issue has now been solved by f4b8158

@achrinza
Copy link
Member

achrinza commented Apr 3, 2022

Closed by: #8026
Continuation of work: #8463

@achrinza achrinza closed this as completed Apr 3, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature parity feature Relations Model relations (has many, etc.)
Projects
None yet
Development

No branches or pull requests

8 participants