jaynetics/delete_recursively

ArgumentError: Polymorphic associations do not support computing the class.

rjnienaber opened this issue · 1 comments

I'm having an issue with a polymorphic association. Here is a minimal test case that reproduces the error:

require 'bundler/inline'

gemfile do
  source 'https://rubygems.org'
  gem 'activerecord', '~> 7.0', '>= 7.0.4.3'
  gem 'delete_recursively', '~> 1.1'
  gem 'sqlite3', '~> 1.6', '>= 1.6.2'
end

ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')

class Task < ActiveRecord::Base
  has_one(:object_statuses, as: :statusable, class_name: :ObjectStatus, dependent: :destroy)
end

class ObjectStatus < ActiveRecord::Base
  belongs_to :statusable, polymorphic: true, inverse_of: :object_statuses
  belongs_to :status, inverse_of: :object_statuses
end

class Status < ActiveRecord::Base
  has_many :object_statuses, inverse_of: :status, dependent: :destroy
end

ActiveRecord::Schema.define do
  create_table :tasks do |t|
    t.string :description
  end

  create_table :object_statuses do |t|
    t.references :statusable, polymorphic: true, index: true
    t.references :status, null: false, foreign_key: true
  end

  create_table :statuses do |t|
    t.string :name, null: false
  end
end

ActiveRecord::Base.transaction do
  t = Task.create(description: "Buy fish and chips")
  s = Status.create(name: 'done')
  ObjectStatus.create(statusable: t, status: s)
end

puts "Task count: #{Task.count}"

DeleteRecursively.all(Task)

puts "Task count: #{Task.count}"

When executed, I get the following output:

-- create_table(:tasks)
   -> 0.0076s
-- create_table(:object_statuses)
   -> 0.0006s
-- create_table(:statuses)
   -> 0.0002s

Task count: 1

activerecord-7.0.4.3/lib/active_record/reflection.rb:423:in `compute_class': Polymorphic associations do not support computing the class. (ArgumentError)
from activerecord-7.0.4.3/lib/active_record/reflection.rb:382:in `klass'
from activerecord-7.0.4.3/lib/active_record/reflection.rb:230:in `inverse_of'
from delete_recursively-1.1.0/lib/delete_recursively.rb:77:in `block (2 levels) in associated_classes'
from delete_recursively-1.1.0/lib/delete_recursively.rb:77:in `any?'
from delete_recursively-1.1.0/lib/delete_recursively.rb:77:in `block in associated_classes'
from delete_recursively-1.1.0/lib/delete_recursively.rb:75:in `select'
from delete_recursively-1.1.0/lib/delete_recursively.rb:75:in `associated_classes'
from delete_recursively-1.1.0/lib/delete_recursively.rb:161:in `block in all'
from delete_recursively-1.1.0/lib/delete_recursively.rb:160:in `each'
from delete_recursively-1.1.0/lib/delete_recursively.rb:160:in `all'
from delete_recursively-1.1.0/lib/delete_recursively.rb:163:in `block (2 levels) in all'
from delete_recursively-1.1.0/lib/delete_recursively.rb:161:in `each'
from delete_recursively-1.1.0/lib/delete_recursively.rb:161:in `block in all'
from delete_recursively-1.1.0/lib/delete_recursively.rb:160:in `each'
from delete_recursively-1.1.0/lib/delete_recursively.rb:160:in `all'
from polymorphic_associations.rb:48:in `<main>'

I find that if I edit this line to ignore the ArgumentError it does what I want I need but I'm not sure that's correct.

hey,

thanks for the report and the excellent reproduction!

i've just released v1.2.1 with this (and a few other things) fixed.

basically what happened is: i never considered that polymorphic relations could have the inverse_of attribute set. it might actually be useless for rails itself, but that's a different story. either way, this case should now be handled properly (though in your particular case, ignoring the error would have been fine as well).

cheers!