Skip to content

feat!: add foreign keys for the slices and their history - #6673

Merged
gharlan merged 2 commits into
6.xfrom
db-schema
Sep 17, 2026
Merged

gharlan merged 2 commits into
6.xfrom
db-schema

Conversation

@gharlan

@gharlan gharlan commented Sep 17, 2026

Copy link
Copy Markdown
Member

The slices were the last core tables left without a foreign key, after the structure and media pool restructuring (#6667, #6668, #6670, #6671) covered everything else.

Schema

  • rex_article_slice and rex_article_slice_history reference rex_article_translation via (article_id, language_id), its primary key. A slice belongs to one article in one language, which is exactly what a translation row is — referencing rex_article and rex_language separately would allow a slice for a language the article does not exist in.
  • Both are ON DELETE CASCADE and ON UPDATE RESTRICT: an auto increment id never changes, so a cascade on update would only silently rewrite rows in the case that something went wrong.
  • find_slices swaps its columns to (article_id, language_id) so the foreign key can use it instead of making InnoDB add an index of its own. snapshot already starts with the two columns.

Handlers

  • LanguageHandler::delete() deleted the slices of the language by hand, ArticleHandler::_deleteArticle() the slices of the article. Both are redundant now and are dropped.
  • The history was cleaned up by neither: deleting an article or a language left its snapshots behind forever. The cascade fixes that.
  • ArticleSliceTest creates the article and its translation its slices hang off, and lets the cascade clean up.

Notes

  • No migration code, as agreed for the 6.x dev state. Existing instances: delete the slices and history rows whose (article_id, language_id) has no row in rex_article_translation, then migrate adds the foreign keys.
  • Verified on a fresh instance with two languages: inserting a slice for an unknown article or an unknown language is rejected, deleting a language removes its slices and history along with its translations, deleting an article removes all of them. Backend smoke test over the structure and content pages, plus the visual test fixture import, which the foreign keys accept as it is.

`rex_article_slice` and `rex_article_slice_history` reference `rex_article_translation` via
`(article_id, language_id)`, its primary key: a slice belongs to one article in one language, which
is exactly what a translation row is. Both cascade on delete and restrict on update — an auto
increment id never changes, so a cascade on update would only silently rewrite rows in the case that
something went wrong.

That makes the manual cleanups redundant, which are dropped: `LanguageHandler::delete()` deleted the
slices of the language by hand, `ArticleHandler::_deleteArticle()` the slices of the article. The
history was cleaned up by neither, so deleting an article or a language left its snapshots behind
forever — the cascade fixes that.

The index `find_slices` swaps its columns to `(article_id, language_id)` so the foreign key can use
it instead of making InnoDB add one of its own. `snapshot` already starts with the two columns.
@gharlan gharlan added this to the REDAXO 6.0 milestone Sep 17, 2026
@rex-bot rex-bot added breaking feature Additional functionality labels Sep 17, 2026
@gharlan
gharlan merged commit 69199fb into 6.x Sep 17, 2026
16 checks passed
@gharlan
gharlan deleted the db-schema branch September 17, 2026 23:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking feature Additional functionality

Development

Successfully merging this pull request may close these issues.

2 participants