Skip to content
This repository was archived by the owner on Apr 17, 2020. It is now read-only.

WIP: feat: add support for many-to-many joins#33

Open
joelmukuthu wants to merge 6 commits intomasterfrom
feat/via
Open

WIP: feat: add support for many-to-many joins#33
joelmukuthu wants to merge 6 commits intomasterfrom
feat/via

Conversation

@joelmukuthu
Copy link
Contributor

@joelmukuthu joelmukuthu commented Oct 31, 2018

Usage:

class User extends Model {}
User.table = 'user';
User.fields = {
  id: 'integer'
};

class Group extends Model {}
Group.table = 'user';
Group.fields = {
  id: 'integer'
};

class GroupMembership extends Model {}
GroupMembership.table = 'group_membership';
GroupMembership.fields = {
  userId: { type: 'integer', references: User.fields.id },
  groupId: { type: 'integer', references: Group.fields.id }
};

User.fetch({
  leftJoin: Group.query
    .via(GroupMembership)
    .as('groups')
});

which yields SQL similar to:

SELECT * FROM  "user" "u" LEFT JOIN "group_membership" "m" ON "m"."user_id" = "u"."id" LEFT JOIN "group" "g" ON "m"."group_id" = "g"."id"

and output such as:

const users = [
  new User({ 
    id: 1, 
    groups: [new Group({ id: 1 })]
  })
];

Closes knorm/knorm#143

@joelmukuthu joelmukuthu force-pushed the feat/via branch 3 times, most recently from ca9cb98 to d328d58 Compare November 3, 2018 21:18
@joelmukuthu
Copy link
Contributor Author

Instead of a via option, it makes more sense to go with an api resembling the current api around joins:

User.fetch({
  leftJoin: GroupMembership.query
    .asJoinQuery(true) // tells @knorm/relations to not include this join in the query results
    .join(Group.query.as('groups'))
});

joelmukuthu and others added 5 commits December 22, 2018 20:49
To allow the `via` option preparation code to re-use it
Instead of using `INNER JOIN` as was the case before
Useful for many-to-many joins:

```js
class User extends Model {}
User.table = 'user';
User.fields = {
  id: 'integer'
};

class Group extends Model {}
Group.table = 'user';
Group.fields = {
  id: 'integer'
};

class GroupMembership extends Model {}
GroupMembership.table = 'group_membership';
GroupMembership.fields = {
  userId: { type: 'integer', references: User.fields.id },
  groupId: { type: 'integer', references: Group.fields.id }
};

User.fetch({
  leftJoin: Group.query
    .via(GroupMembership)
    .as('groups')
});
```
@coveralls
Copy link

Pull Request Test Coverage Report for Build 299

  • 82 of 82 (100.0%) changed or added relevant lines in 1 file are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.2%) to 99.13%

Totals Coverage Status
Change from base Build 281: 0.2%
Covered Lines: 227
Relevant Lines: 227

💛 - Coveralls

new User({ id: 1, groups: [new Group({ id: 1 })] }),
new User({ id: 2, groups: [new Group({ id: 2 })] }),
new User({ id: 3, groups: [new Group({ id: 2 })] }),
new User({ id: 4, groups: null })
Copy link
Contributor

Choose a reason for hiding this comment

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

Wouldn't it make sense to return an empty array here?

Copy link
Contributor Author

@joelmukuthu joelmukuthu Jan 2, 2019

Choose a reason for hiding this comment

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

Yeah, that's a bug: #8 I intend to fix it in v2 (breaking change)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants