GithubHelp home page GithubHelp logo

sk3tch / pg-many-to-many Goto Github PK

View Code? Open in Web Editor NEW

This project forked from graphile-contrib/pg-many-to-many

0.0 1.0 0.0 685 KB

Add connection fields for many-to-many relations

License: MIT License

JavaScript 98.97% Shell 1.03%

pg-many-to-many's Introduction

@graphile-contrib/pg-many-to-many

Package on npm CircleCI

This Graphile Engine plugin adds connection fields for many-to-many relations.

Requires postgraphile@^4.5.0 or graphile-build-pg@^4.5.0

Example:

{
  allPeople {
    nodes {
      personName
      # ๐Ÿ‘‡ many-to-many relation
      teamsByTeamMemberPersonIdAndTeamId {
        nodes {
          teamName
        }
      }
    }
  }
}

Usage

Append this plugin and the additional fields will be added to your schema.

CLI

yarn add postgraphile
yarn add @graphile-contrib/pg-many-to-many
npx postgraphile --append-plugins @graphile-contrib/pg-many-to-many

Library

const express = require("express");
const { postgraphile } = require("postgraphile");
const PgManyToManyPlugin = require("@graphile-contrib/pg-many-to-many");

const app = express();

app.use(
  postgraphile(process.env.DATABASE_URL, "app_public", {
    appendPlugins: [PgManyToManyPlugin],
    graphiql: true,
  })
);

app.listen(5000);

Excluding Fields

To exclude certain many-to-many fields from appering in your GraphQL schema, you can use @omit manyToMany smart comments on constraints and tables.

Here is an example of using a smart comment on a constraint:

create table p.foo (
  id serial primary key,
  name text not null
);

create table p.bar (
  id serial primary key,
  name text not null
);

create table p.qux (
  foo_id int constraint qux_foo_id_fkey references p.foo (id),
  bar_id int constraint qux_bar_id_fkey references p.bar (id),
  primary key (foo_id, bar_id)
);

-- `Foo` and `Bar` would normally have `barsBy...` and `foosBy...` fields,
-- but this smart comment causes the constraint between `qux` and `bar`
-- to be ignored, preventing the fields from being generated.
comment on constraint qux_bar_id_fkey on p.qux is E'@omit manyToMany';

Here is an example of using a smart comment on a table:

create table p.foo (
  id serial primary key,
  name text not null
);

create table p.bar (
  id serial primary key,
  name text not null
);

create table p.corge (
  foo_id int constraint corge_foo_id_fkey references p.foo (id),
  bar_id int constraint corge_bar_id_fkey references p.bar (id),
  primary key (foo_id, bar_id)
);

-- `Foo` and `Bar` would normally have `barsBy...` and `foosBy...` fields,
-- but this smart comment causes `corge` to be excluded from consideration
-- as a junction table, preventing the fields from being generated.
comment on table p.corge is E'@omit manyToMany';

Inflection

To avoid naming conflicts, this plugin uses a verbose naming convention (e.g. teamsByTeamMemberTeamId), similar to how related fields are named by default in PostGraphile v4. You can override this by writing a custom inflector plugin or by using smart comments in your SQL schema.

Inflector Plugin

Writing a custom inflector plugin gives you full control over the GraphQL field names. Here is an example plugin that shortens the field names to just the table name (producing e.g. teams):

โš ๏ธ Warning: Simplifying the field names as shown below will lead to field name conflicts if your junction table has multiple foreign keys referencing the same table. You will need to customize the inflector function to resolve the conflicts.

const { makeAddInflectorsPlugin } = require("graphile-utils");

module.exports = makeAddInflectorsPlugin(
  {
    manyToManyRelationByKeys(
      _leftKeyAttributes,
      _junctionLeftKeyAttributes,
      _junctionRightKeyAttributes,
      _rightKeyAttributes,
      _junctionTable,
      rightTable,
      _junctionLeftConstraint,
      junctionRightConstraint
    ) {
      if (junctionRightConstraint.tags.manyToManyFieldName) {
        return junctionRightConstraint.tags.manyToManyFieldName;
      }
      return this.camelCase(
        `${this.pluralize(this._singularizedTableName(rightTable))}`
      );
    },
    manyToManyRelationByKeysSimple(
      _leftKeyAttributes,
      _junctionLeftKeyAttributes,
      _junctionRightKeyAttributes,
      _rightKeyAttributes,
      _junctionTable,
      rightTable,
      _junctionLeftConstraint,
      junctionRightConstraint
    ) {
      if (junctionRightConstraint.tags.manyToManySimpleFieldName) {
        return junctionRightConstraint.tags.manyToManySimpleFieldName;
      }
      return this.camelCase(
        `${this.pluralize(this._singularizedTableName(rightTable))}-list`
      );
    },
  },
  true // Passing true here allows the plugin to overwrite existing inflectors.
);

For more information on custom inflector plugins, see the makeAddInflectorsPlugin documentation.

Smart Comments

The @manyToManyFieldName and @manyToManySimpleFieldName smart comments allow you to override the field names generated by this plugin.

For example, to rename the Connection field from teamsByTeamMemberTeamId to teams:

comment on constraint membership_team_id_fkey on p.membership is E'@manyToManyFieldName teams';

To rename both the Connection and simple collection fields (assuming simple collections are enabled):

comment on constraint membership_team_id_fkey on p.membership is E'@manyToManyFieldName teams\n@manyToManySimpleFieldName teamsList';

pg-many-to-many's People

Contributors

dependabot[bot] avatar hos avatar mattbretl avatar samlevin avatar singingwolfboy avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.