Navigation Menu

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

after_commit(on: :update) is only triggered with the changes of the first update to the record #39972

Closed
chrismaximin opened this issue Aug 2, 2020 · 2 comments

Comments

@chrismaximin
Copy link
Contributor

chrismaximin commented Aug 2, 2020

Steps to reproduce

begin
  require 'bundler/inline'
rescue LoadError => e
  $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
  raise e
end

gemfile(true) do
  source 'https://rubygems.org'

  gem 'activerecord', "6.0.3"
  gem 'sqlite3'
end

require 'active_record'
require 'minitest/autorun'
require 'logger'

Minitest::Test = MiniTest::Unit::TestCase unless defined?(Minitest::Test)

ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  create_table :post_items, force: true do |t|
    t.string :title
  end
end

class PostItem < ActiveRecord::Base
  after_commit :my_callback, on: :update

  private
    def my_callback
      puts "#{id}: previous_changes = #{previous_changes.inspect}"
    end
end

class BugTest < Minitest::Test
  def test_stuff
    PostItem.create!
    PostItem.create!

    PostItem.transaction do
      PostItem.first.update!(title: "first post title update 1")
      PostItem.first.update!(title: "first post title update 2")
      PostItem.last.update!(title: "last post title update 1")
      PostItem.last.update!(title: "last post title update 2")
    end
  end
end

Expected behavior

Output:

1: previous_changes = {"title"=>[nil, "first post title update 2"]}
2: previous_changes = {"title"=>[nil, "last post title update 2"]}

Actual behavior

Output:

1: previous_changes = {"title"=>[nil, "first post title update 1"]}
2: previous_changes = {"title"=>[nil, "last post title update 1"]}

System configuration

Rails version: 6.0.3
Ruby version: 2.7.1

Full logs

D, [2020-08-02T18:00:29.208603 #5622] DEBUG -- : (0.1ms) begin transaction
D, [2020-08-02T18:00:29.208798 #5622] DEBUG -- : PostItem Create (0.1ms) INSERT INTO "post_items" DEFAULT VALUES
D, [2020-08-02T18:00:29.209030 #5622] DEBUG -- : (0.0ms) commit transaction
D, [2020-08-02T18:00:29.209380 #5622] DEBUG -- : (0.0ms) begin transaction
D, [2020-08-02T18:00:29.209490 #5622] DEBUG -- : PostItem Create (0.1ms) INSERT INTO "post_items" DEFAULT VALUES
D, [2020-08-02T18:00:29.209598 #5622] DEBUG -- : (0.0ms) commit transaction
D, [2020-08-02T18:00:29.210048 #5622] DEBUG -- : (0.0ms) begin transaction
D, [2020-08-02T18:00:29.210218 #5622] DEBUG -- : PostItem Load (0.1ms) SELECT "post_items".* FROM "post_items" ORDER BY "post_items"."id" ASC LIMIT ? [["LIMIT", 1]]
D, [2020-08-02T18:00:29.210661 #5622] DEBUG -- : PostItem Update (0.0ms) UPDATE "post_items" SET "title" = ? WHERE "post_items"."id" = ? [["title", "first post title update 1"], ["id", 1]]
D, [2020-08-02T18:00:29.210884 #5622] DEBUG -- : PostItem Load (0.0ms) SELECT "post_items".* FROM "post_items" ORDER BY "post_items"."id" ASC LIMIT ? [["LIMIT", 1]]
D, [2020-08-02T18:00:29.211132 #5622] DEBUG -- : PostItem Update (0.0ms) UPDATE "post_items" SET "title" = ? WHERE "post_items"."id" = ? [["title", "first post title update 2"], ["id", 1]]
D, [2020-08-02T18:00:29.211340 #5622] DEBUG -- : PostItem Load (0.0ms) SELECT "post_items".* FROM "post_items" ORDER BY "post_items"."id" DESC LIMIT ? [["LIMIT", 1]]
D, [2020-08-02T18:00:29.211581 #5622] DEBUG -- : PostItem Update (0.0ms) UPDATE "post_items" SET "title" = ? WHERE "post_items"."id" = ? [["title", "last post title update 1"], ["id", 2]]
D, [2020-08-02T18:00:29.211746 #5622] DEBUG -- : PostItem Load (0.0ms) SELECT "post_items".* FROM "post_items" ORDER BY "post_items"."id" DESC LIMIT ? [["LIMIT", 1]]
D, [2020-08-02T18:00:29.211973 #5622] DEBUG -- : PostItem Update (0.0ms) UPDATE "post_items" SET "title" = ? WHERE "post_items"."id" = ? [["title", "last post title update 2"], ["id", 2]]
D, [2020-08-02T18:00:29.212094 #5622] DEBUG -- : (0.0ms) commit transaction
1: previous_changes = {"title"=>[nil, "first post title update 1"]}
2: previous_changes = {"title"=>[nil, "last post title update 1"]}

@chrismaximin chrismaximin changed the title after_commit(on: :update_ is only triggered with the changes of the first changes to the record after_commit(on: :update) is only triggered with the changes of the first changes to the record Aug 2, 2020
@chrismaximin chrismaximin changed the title after_commit(on: :update) is only triggered with the changes of the first changes to the record after_commit(on: :update) is only triggered with the changes of the first update to the record Aug 2, 2020
@tgxworld
Copy link
Contributor

tgxworld commented Aug 3, 2020

Thank you for the detailed bug report 👍 This is actually a known issue with the discussion currently on going in #39400

@jonathanhefner
Copy link
Member

Closing in favor of #39400. Thank you for the report, @christophemaximin! And thank you for reviewing, @tgxworld! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants