diff --git a/lib/activerecord/delay_touching.rb b/lib/activerecord/delay_touching.rb index a326802..eeedfe6 100644 --- a/lib/activerecord/delay_touching.rb +++ b/lib/activerecord/delay_touching.rb @@ -95,7 +95,7 @@ def self.touch_records(attr, klass, records) end end - klass.unscoped.where(klass.primary_key => records).update_all(changes) + klass.unscoped.where(klass.primary_key => records.select(&:persisted?)).update_all(changes) end state.updated attr, records records.each { |record| record.run_callbacks(:touch) } diff --git a/spec/activerecord/delay_touching_spec.rb b/spec/activerecord/delay_touching_spec.rb index f504c7a..a95c1a6 100644 --- a/spec/activerecord/delay_touching_spec.rb +++ b/spec/activerecord/delay_touching_spec.rb @@ -195,6 +195,24 @@ end + it 'does not attempt to update is NULL primary key' do + bad_update = /UPDATE "tags" SET "updated_at" = .* WHERE "tags"\."id" IS NULL/ + expect(ActiveRecord::Base.connection).to receive(:update).and_wrap_original do |m, *args| + arel_stmt = args.first + expect(arel_stmt.to_sql).to_not match(bad_update) + m.call(*args) + end + + ActiveRecord::Base.delay_touching do + ActiveRecord::Base.transaction do + # touch any record through a custom relationship table + # NOTE: does not happen with a has_and_belongs_to_many relationship + post = Post.create! + post.tags.create! + raise ActiveRecord::Rollback + end + end + end end def expect_updates(tables) diff --git a/spec/support/models.rb b/spec/support/models.rb index 17ab68c..8bf9744 100644 --- a/spec/support/models.rb +++ b/spec/support/models.rb @@ -8,6 +8,9 @@ class Pet < ActiveRecord::Base class Post < ActiveRecord::Base has_many :comments, dependent: :destroy + + has_many :tag_relationships, dependent: :destroy + has_many :tags, through: :tag_relationships end class User < ActiveRecord::Base @@ -18,3 +21,13 @@ class Comment < ActiveRecord::Base belongs_to :post, touch: true belongs_to :user, touch: true end + +class Tag < ActiveRecord::Base + has_many :tag_relationships, dependent: :destroy + has_many :posts, through: :tag_relationships +end + +class TagRelationship < ActiveRecord::Base + belongs_to :tag, touch: true + belongs_to :post +end \ No newline at end of file diff --git a/spec/support/schema.rb b/spec/support/schema.rb index 8ba9290..3b2a26d 100644 --- a/spec/support/schema.rb +++ b/spec/support/schema.rb @@ -30,4 +30,12 @@ t.timestamps null: false end + create_table :tags, force: true do |t| + t.timestamps null: false + end + + create_table :tag_relationships, force: true do |t| + t.integer :tag_id + t.integer :post_id + end end