Add Relation#on_conflict with a DSL for upserts - #441
Draft
flash-gordon wants to merge 1 commit into
Draft
flash-gordon wants to merge 1 commit into
flash-gordon wants to merge 1 commit into
Conversation
Member
Author
|
It's an AI doing, I'll review it soon. I just accumulated a dozen upserts in the app and I've decided it's enough to model a DSL worth having (and matching our style!). |
flash-gordon
marked this pull request as draft
September 10, 2026 17:42
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Upserts required dropping down to Sequel with
dataset.insert_conflict(target: ..., update: { name: Sequel[:excluded][:name] }), andPostgres::Upsertcovers single inserts configured at the class level only. This makes ON CONFLICT a part of the relation, so it composes the waywheredoes and any insert through such a relation becomes an upsert:do_updateaccepts a block evaluated with a DSL: attributes refer to the existing row,excludedto the row proposed for insertion, functions are resolved via the virtual row like inwhere.setandwherereturn immutable values and chain:Commands::Createis restrictable now, hence the relation flows into commands and changesets, which return the upserted rows via RETURNING on PostgreSQL:Works with PostgreSQL and SQLite, MySQL raises
UnsupportedFeatureError.Relation#upsertandPostgres::Upsertare left untouched.