Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
1122: Proposal: Add `path` column to categories table as `ltree` type to make tree traversing easier r=carols10cents a=erewok ## Description This is a proposal inspired by tickets ([1](#1093), and [2](#721)) with the goal of eventually revealing more information about categories on pages where category information is available. It is also motivated by the current application code surrounding categories, which contains lots of SQL with operations like this: `split_part(c2.slug, '::', 1)`. This PR is intended as a suggestion for what to do with the `categories` table. Following are changes included here: - Adds a `path` column as a Postgresql `ltree` type to the `categories` table in order to more easily query trees of categories and subcategories. This allows navigating trees of arbitrary depth and potentially more ergonomic path-finding queries. - Adds a `parent_categories` method to `Category`, which returns parent categories _in order of traversal_ from root to this node. ## Trade-offs to this Approach ### Pros - Easily handle trees of arbitrary depth, ex: "category::sub-category::sub-catgeory-A::sub-category-A-1". - Makes queries to find a whole tree of nodes simpler (and possibly quicker?). Ex: `select slug, path from categories where path <@ 'root.web_programming';` - Makes finding all root-level nodes simpler (assuming one is cool with the syntax). Ex: `select slug, path from categories where path ~ 'root.*{1}';` - Makes finding the direct path from the root node to a particular node easier (see `parent_categories` method). Ex: `select slug, path from categories where path @> 'root.web_programming.http_client' order by path;` - Invisible to current application code: nothing needs to be updated to handle the `path` column because it happens via database triggers. (This could also be a _con_ depending on one's perspective.) ### Cons - Postgresql only (harder to switch databases in the future) - Makes certain characters in slugs disallowed: `[',",-]`. Path labels must consist of "A-Za-z0-9_" separated by "." We swap `-` for `_` and `::` for `.` in the included Postgresql procedure. - This `path` column is nowhere in application code, so this is all hand-written SQL (but the current solution is doing that as well). - Error messages are opaque if you happen to have a bad character in a slug: ``` cargo_registry=# update categories set slug = 'test-new::bla$bla-::parent::child' where slug = 'test-new::parent::child'; ERROR: syntax error at position 17 CONTEXT: PL/pgSQL function set_category_path_to_slug() line 3 at assignment ``` ## Notes - [x] Needs a test for the `parent_categories` method. Co-authored-by: Erik Aker <eraker@gmail.com> Co-authored-by: Ashe Connor <ashe@kivikakk.ee> Co-authored-by: Carol (Nichols || Goulding) <carol.nichols@gmail.com>
- Loading branch information