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

Error with DatabaseConsistency::Checkerrs::MissingAssociationClassChecker #248

Open
lloydwatkin opened this issue Jan 8, 2025 · 5 comments

Comments

@lloydwatkin
Copy link

lloydwatkin commented Jan 8, 2025

<===begin===>
Metadata:
model: Story
association: locatable
checker: DatabaseConsistency::Checkers::ForeignKeyTypeChecker
Stack trace:
~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/reflection.rb:516:in `compute_class': �[1mThe Locatable model class for the Story#locatable association is not an ActiveRecord::Base subclass. (�[1;4mArgumentError�[m�[1m)�[m

�[1m          raise ArgumentError, "The #{name} model class for the #{active_record}##{self.name} association is not an ActiveRecord::Base subclass."�[m
�[1m                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[m
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/reflection.rb:439:in `_klass'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/reflection.rb:431:in `klass'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb:27:in `preconditions'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/checkers/base_checker.rb:33:in `report'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/checkers/base_checker.rb:44:in `report_if_enabled?'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:17:in `block (6 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:20:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:8:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:15:in `block (5 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:14:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:14:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:14:in `block (4 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:20:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:8:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:13:in `block (3 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:12:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:12:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:12:in `block (2 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:20:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:8:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:11:in `block in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:10:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:10:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:10:in `check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:27:in `reports'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:8:in `block in reports'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:7:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:7:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:7:in `reports'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency.rb:117:in `run'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/bin/database_consistency:78:in `<top (required)>'
	from ~/.rbenv/versions/3.3.5/bin/database_consistency:25:in `load'
	from ~/.rbenv/versions/3.3.5/bin/database_consistency:25:in `<top (required)>'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli/exec.rb:58:in `load'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli/exec.rb:58:in `kernel_load'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli/exec.rb:23:in `run'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli.rb:492:in `exec'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli.rb:34:in `dispatch'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli.rb:28:in `start'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/exe/bundle:37:in `block in <top (required)>'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/exe/bundle:29:in `<top (required)>'
	from ~/.rbenv/versions/3.3.5/bin/bundle:25:in `load'
	from ~/.rbenv/versions/3.3.5/bin/bundle:25:in `<main>'
<===end===>

The locatable association is in a concern (included below). The model itself extends ApplicationRecord which itself extends ActiveRecord::Base however this is the same for all of our models.

# frozen_string_literal: true

module Locatable
  extend ActiveSupport::Concern

  included do
    has_one :locality_information, as: :locatable
  end
end

Have also tried it as follows with the same error:

# frozen_string_literal: true

module Locatable
  extend ActiveSupport::Concern

  included do
    has_one :locality_information, as: :locatable, class_name: "LocalityInformation"
  end
end
@lloydwatkin
Copy link
Author

Also fails on another checker:

<===begin===>
Metadata:
model: User
association: locatable
checker: DatabaseConsistency::Checkers::ForeignKeyTypeChecker
Stack trace:
~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/reflection.rb:516:in `compute_class': �[1mThe Locatable model class for the User#locatable association is not an ActiveRecord::Base subclass. (�[1;4mArgumentError�[m�[1m)�[m

�[1m          raise ArgumentError, "The #{name} model class for the #{active_record}##{self.name} association is not an ActiveRecord::Base subclass."�[m
�[1m                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^�[m
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/reflection.rb:439:in `_klass'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/activerecord-7.2.2.1/lib/active_record/reflection.rb:431:in `klass'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/checkers/association_checkers/foreign_key_type_checker.rb:27:in `preconditions'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/checkers/base_checker.rb:33:in `report'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/checkers/base_checker.rb:44:in `report_if_enabled?'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:17:in `block (6 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:20:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:8:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:15:in `block (5 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:14:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:14:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:14:in `block (4 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:20:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:8:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:13:in `block (3 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:12:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:12:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:12:in `block (2 levels) in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:20:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/debug_context.rb:8:in `with'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:11:in `block in check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:10:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:10:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/associations_processor.rb:10:in `check'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:27:in `reports'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:8:in `block in reports'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:7:in `each'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:7:in `flat_map'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency/processors/base_processor.rb:7:in `reports'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/lib/database_consistency.rb:117:in `run'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/database_consistency-2.0.3/bin/database_consistency:78:in `<top (required)>'
	from ~/.rbenv/versions/3.3.5/bin/database_consistency:25:in `load'
	from ~/.rbenv/versions/3.3.5/bin/database_consistency:25:in `<top (required)>'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli/exec.rb:58:in `load'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli/exec.rb:58:in `kernel_load'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli/exec.rb:23:in `run'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli.rb:492:in `exec'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli.rb:34:in `dispatch'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/cli.rb:28:in `start'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/exe/bundle:37:in `block in <top (required)>'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
	from ~/.rbenv/versions/3.3.5/lib/ruby/gems/3.3.0/gems/bundler-2.4.22/exe/bundle:29:in `<top (required)>'
	from ~/.rbenv/versions/3.3.5/bin/bundle:25:in `load'
	from ~/.rbenv/versions/3.3.5/bin/bundle:25:in `<main>'
<===end===>

@lloydwatkin
Copy link
Author

lloydwatkin commented Jan 8, 2025

If I add a little hack into reflection.rb as follows:

      def _klass(class_name) # :nodoc:
        if active_record.name.demodulize == class_name
          return compute_class("::#{class_name}") rescue NameError
        end
        if class_name == 'Locatable' 
          class_name = "LocalityInformation"   
          puts "Renamed #{class_name} ~~~~********"
          puts "#{compute_class(class_name)} ~~~~~"
          puts "######"
          
        else
         # puts class_name
        end


        compute_class(class_name)
      end

I then get the errors,

  • MissingIndexChecker fail Story locatable associated model should have proper index in the database. Total grouped offenses: 2
  • ForeignKeyTypeChecker fail Story locatable association (locatable) of class (Story) relies on field (locality_information_id) of table (locality_information) but it is missing
  • ForeignKeyTypeChecker fail User locatable association (locatable) of class (User) relies on field (locality_information_id) of table (locality_information) but it is missing

Our LocalityInformation table has two columns locatable_type/locatable_id and is set up as follows:

class LocalityInformation < ApplicationRecord
  self.table_name = "locality_information"

  belongs_to :locatable, polymorphic: true, optional: true

@lloydwatkin
Copy link
Author

I'm trying to integrate database_consistency into our CI. I wonder if there is a way to run the existing checks, but ignore these errors (right now it exits with 1 as you would expect).

@djezzzl
Copy link
Owner

djezzzl commented Jan 9, 2025

Hi @lloydwatkin!

Thank you for using the gem and reporting the issues!

I haven't yet finished reading all of them, but at least it looks manageable to fix first.

Would you like to contribute? I will support you with the PR review and release. If you can't, I will do my best to fix it and check others as soon as possible.

@djezzzl
Copy link
Owner

djezzzl commented Jan 9, 2025

Oh, I just finished reading.

There is only one problem with the way the gem determines an association class.

I'm trying to integrate database_consistency into our CI. I wonder if there is a way to run the existing checks, but ignore these errors (right now it exits with 1 as you would expect).

Yes, you can disable the checks temporarily with the .database_consistency.yml file. You can read how the configuration should look like with our documentation. https://github.com/djezzzl/database_consistency/wiki/configuration

Something like:

User:
  locatable: 
    ForeignKeyTypeChecker:
      enabled: false
Story:
  locatable: 
    ForeignKeyTypeChecker:
      enabled: false

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

No branches or pull requests

2 participants