Skip to content

Commit 4eddb9c

Browse files
authored
feat: omit records from table that belong to an archived record (#16)
1 parent b6af838 commit 4eddb9c

File tree

3 files changed

+362
-46
lines changed

3 files changed

+362
-46
lines changed

README.md

Lines changed: 70 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ example you could hide drafts via a `published_at` column and require an
99
explicit `includeDrafts: YES` setting to show them.
1010

1111
It's possible (and common) to use this plugin multiple times (for different
12-
column names/meanings).
12+
column names/meanings) - when you do so you must use a different keyword for
13+
each plugin invocation.
1314

1415
## Installing
1516

@@ -23,27 +24,48 @@ yarn add postgraphile @graphile-contrib/pg-omit-archived
2324

2425
## Usage
2526

26-
Add a boolean column `is_archived` to your table to indicate whether the record
27-
should be skipped over by default or not:
27+
Add a column to your table to indicate whether the record should be skipped over
28+
by default or not, and then append this plugin to your PostGraphile options. CLI
29+
usage is more restrictive than library usage, so if you want more powerful
30+
integration we recommend you use PostGraphile in library (middleware) mode.
31+
32+
### Usage - CLI
33+
34+
If you're using the CLI then you must use a boolean `is_archived` column:
2835

2936
```sql
3037
alter table my_table add column is_archived boolean not null default false;
3138
```
3239

33-
Then append this plugin to your PostGraphile options.
34-
35-
### Usage - CLI
36-
37-
When using this via the CLI, the database column must be named `is_archived`.
40+
Then append this plugin with `--append-plugins`:
3841

3942
```
4043
postgraphile --append-plugins @graphile-contrib/pg-omit-archived -c postgres:///my_db
4144
```
4245

4346
### Usage - Library
4447

45-
You can modify the archived column name when using PostGraphile as a library,
46-
e.g.:
48+
If you're using PostGraphile in library (middleware) mode then you have more
49+
configuration options and you can specify a column that's _either_ boolean _or_
50+
nullable; a nullable timestamptz column is a popular choice:
51+
52+
```sql
53+
alter table my_table add column archived_at timestamptz;
54+
```
55+
56+
If you're not using a boolean `is_archived` column then you must specify the
57+
column name, which you can do via the `pgArchivedColumnName` option.
58+
59+
You can also tell the plugin to invert the include/exclude logic with the
60+
`pgArchivedColumnImpliesVisible` option (e.g. if you're using `is_published`
61+
you'd set `pgArchivedColumnImpliesVisible: true` rather than the default
62+
`pgArchivedColumnImpliesVisible: false` which would be appropriate for
63+
`is_draft`). More information on this below.
64+
65+
Another option is to have the plugin apply to related records with the
66+
`pgArchivedRelations: true` option - more on this below.
67+
68+
Example:
4769

4870
```js
4971
const express = require("express");
@@ -61,6 +83,7 @@ app.use(
6183
graphileBuildOptions: {
6284
pgArchivedColumnName: "is_archived",
6385
pgArchivedColumnImpliesVisible: false,
86+
pgArchivedRelations: false,
6487
},
6588
/* ☝️☝️☝️ */
6689
}),
@@ -69,7 +92,10 @@ app.use(
6992
app.listen(process.env.PORT || 3000);
7093
```
7194

72-
You can also use the plugin multiple times for different columns, for example:
95+
You can also use the plugin multiple times for different columns using the
96+
`custom(keyword)` plugin factory. When you do this you supply a `keyword` and
97+
all of the options are based on this keyword so you can configure each plugin
98+
individually (we also look for the column `is_${keyword}`). For example:
7399

74100
```js
75101
const express = require("express");
@@ -90,19 +116,29 @@ app.use(
90116
customPgOmitArchived("draft"), // e.g. draft vs published
91117
],
92118
graphileBuildOptions: {
93-
// Options for 'archived':
94-
pgArchivedColumnName: "is_archived", // boolean column -> checked as "IS NOT TRUE"
95-
pgArchivedColumnImpliesVisible: false, // when true, hide; when false, visible
119+
/* -------- Options for 'archived' -------- */
120+
// Boolean column -> checked as "IS NOT TRUE":
121+
pgArchivedColumnName: "is_archived",
122+
// When true, hide; when false, visible:
123+
pgArchivedColumnImpliesVisible: false,
124+
// Only add includeArchived to tables with is_archived column:
125+
pgArchivedRelations: false,
96126

97-
// Options for 'deleted':
98-
pgDeletedColumnName: "deleted_at", // non-boolean column -> checked as "IS NULL"
127+
/* -------- Options for 'deleted' -------- */
128+
// Non-boolean column -> checked as "IS NULL":
129+
pgDeletedColumnName: "deleted_at",
130+
// Also add includeDeleted to tables which belong to a table with
131+
// deleted_at column:
132+
pgArchivedRelations: true,
99133

100-
// Options for 'template':
134+
/* -------- Options for 'template' -------- */
101135
pgTemplateColumnName: "is_template",
102136

103-
// Options for 'draft':
104-
pgDraftColumnName: "is_published", // Column name doesn't have to match keyword name
105-
pgDraftColumnImpliesVisible: true, // When true -> published -> visible; when false -> unpublished -> hiddel
137+
/* -------- Options for 'draft' -------- */
138+
// Column name doesn't have to match keyword name:
139+
pgDraftColumnName: "is_published",
140+
// When true -> published -> visible; when false -> unpublished -> hidden
141+
pgDraftColumnImpliesVisible: true,
106142
},
107143
/* ☝️☝️☝️ */
108144
}),
@@ -115,19 +151,29 @@ app.listen(process.env.PORT || 3000);
115151

116152
By default we'll look for a column named after your keyword (e.g. if you use the
117153
'deleted' keyword, we'll look for an `is_deleted` column). You may override the
118-
column adding the `pg<Keyword>ColumnName: 'my_column_name_here'` setting to
119-
`graphileBuildOptions`, where `<Keyword>` is your keyword with the first
120-
character uppercased (see above for examples).
154+
column adding the `pg<Keyword>ColumnName: 'my_column_name_here'` (e.g.
155+
`pgDeletedColumnName: 'deleted_at'`) setting to `graphileBuildOptions`, where
156+
`<Keyword>` is your keyword with the first character uppercased (see above for
157+
examples).
121158

122159
This plugin was built expecting to hide things when `true` (boolean) or non-null
123160
(e.g. nullable timestamp) - this works well for things like `is_archived`,
124161
`deleted_at`, and `is_template`. However sometimes you want this inverse of this
125162
behaviour; e.g. if your column is `published_at` you'd want it visible when
126163
non-null and hidden when null. To invert the behaviour, add the
127-
`pg<Keyword>ColumnImpliesVisible: true` setting to `graphileBuildOptions`, where
164+
`pg<Keyword>ColumnImpliesVisible: true` (e.g.
165+
`pgDraftColumnImpliesVisible: true`) setting to `graphileBuildOptions`, where
128166
`<Keyword>` is your keyword with the first character uppercased (see above for
129167
examples).
130168

169+
By default this plugin only adds the `include<Keyword>` (e.g. `includeArchived`)
170+
argument to collections for tables that have the relevant (e.g. `is_archived`)
171+
column. Sometimes however you want to expand this behaviour to tables that
172+
"belong to" this table. To achieve this, use the `pg<Keyword>Relations: true`
173+
(e.g. `pgArchivedRelations: true`) option. You should use this sparingly as it's
174+
not implemented particularly efficiently, and it also will make your schema
175+
somewhat larger/more complex.
176+
131177
## Behaviour
132178

133179
Root level query fields will omit archived records by default.

0 commit comments

Comments
 (0)