Support updating records by id via :on_duplicate_key_update (#187)#220
Merged
Conversation
Issue #187 asked for updating existing records by id during import. This is already possible through activerecord-import's upsert support, but it was untested and only vaguely documented. Add a spec proving a single import updates colliding rows (matched on :id) and inserts non-colliding ones in one pass, and replace the hand-wavy README note with a concrete example plus the validate:false and callbacks caveats.
MySQL rejects the :conflict_target hash key (treats it as a column: "Unknown column 'conflict_target'"). It infers the conflicting key on its own, so it takes the bare column list, while PostgreSQL/SQLite need the explicit conflict_target. Branch the option in the spec and document both shapes in the README.
9b449e3 to
ba06636
Compare
This was referenced Jun 15, 2026
Merged
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.
Closes #187.
Context
Issue #187 asked for a way to update existing records based on an id column during import, instead of only inserting. This is already achievable through
activerecord-import's upsert support (:on_duplicate_key_update), but the behaviour was untested and the README only mentioned it in passing ("For databases that support upserts you can use:on_duplicate_key_updateinstead.").This PR proves it works and documents it properly.
What's here
Spec (
spec/import_spec.rb): a new context under authors already exist that importsauthors_with_ids.csvwithand asserts that a single import:
Successfully imported 2 authors.README: replaced the one-line note with a concrete example and the two caveats that bite in practice:
conflict_targetmust name the unique column(s); MySQL infers and ignores it.validatemust be off for id-based upserts —activerecord-importruns uniqueness validations against the very rows the upsert is about to overwrite, so a model-levelvalidates_uniqueness_ofwould reject the update (verified: withvalidate: truethe existing-row update is dropped with "Last name has already been taken").Verification
bundle exec rspec spec/import_spec.rb→ 52 examples, 0 failures (3 new). Run locally on SQLite 3.53 / Rails 7.1 / Active Admin 3.2.