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: :create" callback is called when destroying model instance with activerecord 6.0.0.rc1 #473

Open
eitoball opened this issue May 29, 2019 · 7 comments
Labels

Comments

@eitoball
Copy link

When destroying model instance in activerecord 6.0.0.rc1, it seems thatafter_commit on: :create callback is called.

A sample code that can reproduce this isuue is attached in "Code" section. When running this code with activerecord 6.0.0.rc1, it outputs ">>>>> after_commit_on_create" line twice. With activerecord 5.2.3, it outputs once.

Is this issue in paranoia? Or am I setting callbacks in wrong way?

TIA

Code

# frozen_string_literal: true

require 'active_record'
require 'paranoia'
require 'sqlite3'

ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
Class.new(ActiveRecord::Migration[5.2]) do
  def change
    create_table :items do |t|
      t.datetime :deleted_at
    end
  end
end.migrate(:up)

class Item < ActiveRecord::Base
  acts_as_paranoid

  after_commit :after_commit_on_create, on: :create

  def after_commit_on_create
    warn '>>>>> after_commit_on_create'
  end
end

puts 'Creating an item'
item = Item.create!

puts 'Destroying item'
item.destroy

Output

==  : migrating ===============================================================
-- create_table(:items, {})
   -> 0.0004s
==  : migrated (0.0005s) ======================================================

Creating an item
>>>>> after_commit_on_create
Destroying item
>>>>> after_commit_on_create

Gemfile

# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }

gem 'activerecord', '6.0.0.rc1'
gem 'paranoia'
gem 'sqlite3'

Gemfile.lock

GEM
  remote: https://rubygems.org/
  specs:
    activemodel (6.0.0.rc1)
      activesupport (= 6.0.0.rc1)
    activerecord (6.0.0.rc1)
      activemodel (= 6.0.0.rc1)
      activesupport (= 6.0.0.rc1)
    activesupport (6.0.0.rc1)
      concurrent-ruby (~> 1.0, >= 1.0.2)
      i18n (>= 0.7, < 2)
      minitest (~> 5.1)
      tzinfo (~> 1.1)
      zeitwerk (~> 2.1, >= 2.1.4)
    concurrent-ruby (1.1.5)
    i18n (1.6.0)
      concurrent-ruby (~> 1.0)
    minitest (5.11.3)
    paranoia (2.4.2)
      activerecord (>= 4.0, < 6.1)
    sqlite3 (1.4.1)
    thread_safe (0.3.6)
    tzinfo (1.2.5)
      thread_safe (~> 0.1)
    zeitwerk (2.1.6)

PLATFORMS
  ruby

DEPENDENCIES
  activerecord (= 6.0.0.rc1)
  paranoia
  sqlite3

BUNDLED WITH
   1.17.2
@bishosilwal
Copy link

@eitoball yo can use object.deleted? on if block like after_commit :after_commit_on_create, on: :create, if: -> { !self.deleted? } . In this way you can block after_commit call if object is soft deleted.

@johnmosesman
Copy link

johnmosesman commented Sep 13, 2019

Ran into this same thing, @bishosilwal 's suggestion worked as a stop gap.

Tried to poke around a little bit but I don't know that I found anything useful. Rails does replace the use of add_to_transaction in a PR here. Maybe that's somehow related?

@anirbanmu
Copy link

I am hitting this now in the process of upgrading rails 5.2 to 6.0 as well. I suppose I will use the if: -> { !self.deleted? } workaround since it doesn't seem like this is likely to get fixed any time soon.

@arlando
Copy link

arlando commented May 18, 2020

@anirbanmu thanks for the pointer. I would advise against using the lambda. I ran into a strange regression with callback order when performing methods against ActiveRecord models in each blocks.

I didn't have a chance to look deeper but would advise to use a Proc or a symbol pointing to a method defined on the class as per the Rails docs here: https://guides.rubyonrails.org/active_record_callbacks.html#conditional-callbacks.

@anirbanmu
Copy link

@arlando that is very interesting that a lambda caused you a problem vs a Proc. As far as my understanding goes, Proc & lambda are very similar albeit with small differences (return keyword difference, argument validation etc.). Would be interesting to know what the cause of the issue you saw was.

See this section https://api.rubyonrails.org/classes/ActiveSupport/Callbacks/ClassMethods.html#method-i-set_callback It seems to say you can use proc or lambda: If a proc, lambda, or block is given, its body is evaluated in the context of the current object. It can also optionally accept the current object as an argument. Maybe paranoia changes the assumptions here? Not sure.

@arlando
Copy link

arlando commented May 18, 2020

@anirbanmu thanks for the pointer if I have some time I'll set up a gist showing the issue.

@janko
Copy link

janko commented Jan 4, 2023

Hitting the same bug on Rails 6.1.6.1, the after_create_commit callback is being called on destroy. I don't see anything being stale in this issue, there is a self-contained example reproducing the problem, I think the label should be removed.

@mathieujobin mathieujobin added bug and removed stale labels May 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants