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

Feature Request: reference relations in Models #11

Open
5 tasks done
itsezc opened this issue Feb 2, 2023 · 0 comments
Open
5 tasks done

Feature Request: reference relations in Models #11

itsezc opened this issue Feb 2, 2023 · 0 comments

Comments

@itsezc
Copy link
Owner

itsezc commented Feb 2, 2023

Preliminary checklist

  • I understand that all communication must be in English
  • I read the Documentation
  • I read the Contributing guide
  • I agree to follow the Code of Conduct
  • I searched the issues and discussions but couldn't find anything (or linked relevant results below)

Problem

It would be very intuitive where a Model can reference relations, here is an example use case:

@Table({ name: 'follows', edge: true })
export class Followers extends Model 
{
    @Field({ name: 'in' })
    inside!: User;
    out!: User;
}

@Table({ name: 'follows', edge: true })
export class Following extends Model 
{
    @Field({ name: 'in' })
    inside!: User;

    out!: User;
}

@Table<User>({
    name: 'user',
    permissions: ({ username }) => [
        [['CREATE', 'UPDATE', 'SELECT'], true],
        ['DELETE', AdminScope]
    ],
    auditable: true,
})
export class User extends Model
{
    @Field({ index: 'unique' })
    username: string;

    @Field({ assert: 'email', name: 'email_address', index: 'unique' })
    email?: string;

    bestFriend?: User;

    followers?: Followers[];

    following?: Following[];
}

being able to select, relational fields via the select method
eg. User.select(['username', 'followers', 'following']).build()
SELECT username, <-follows<-user as followers, ->follows->user as following FROM user
also to be able to fetch relational fields via the fetch method
eg. User.select(['username', 'followers', 'following']).fetch(['followers', 'following']).build();

there are several issues which need to be addressed

  1. the schema generator must know how to handle the relational fields (i.e do not mistake them for record fields)
  2. the select builder must also know how to differentiate between relational and record fields

one solution could be to create a new decorator called @relational
this decorator would be used to decorate the relational fields
@relational(Followers) (could also potentially add more props to this decorator)
the schema generator would then know to ignore these fields
the select builder would also know to ignore these fields

another solution could be to add a new property to the @field decorator
eg. @field({ relation: Followers })

a third solution could be to expand the current select method to accept an instance of a select builder
eg. User.select(['username')]).select(Followers.select())
or expand the in, out logic to handle the relational query

However, further investigation is needed on how one might reference deeply nested relations and an alternative API maybe necessary than the one currently suggested.

Solution

Relation references could be tagged with a decorator i.e. @FieldRelation()

and therefore be usable in Models:

export class Account extends Model
{
     @FieldRelation({ direction: 'in' })
     friends: Friend[]
}

Alternatives

No response

Contribution

No, I cannot contribute further

Keywords

relations, model, query, API

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

1 participant