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

Crashes when using invalid source in a has_many through: relation #181

Closed
mediafinger opened this issue Aug 2, 2024 · 1 comment · Fixed by #202 · May be fixed by #198
Closed

Crashes when using invalid source in a has_many through: relation #181

mediafinger opened this issue Aug 2, 2024 · 1 comment · Fixed by #202 · May be fixed by #198

Comments

@mediafinger
Copy link

mediafinger commented Aug 2, 2024

Crashes when using invalid source in a has_many through: relation

I misconfigured an ActiveRecord relation and didn't notice, as the app and specs were running fine (the app doesn't use the relation directly yet). But when running active_record_doctor I only received an error message which left me quite clueless - see below:

  • active_record_doctor v1.14.0
  • rails 7.2.0.beta3
  • ruby 3.3.4
$> rake active_record_doctor --trace

** Invoke active_record_doctor (first_time)
** Invoke active_record_doctor:setup (first_time)
** Invoke environment (first_time)
** Execute environment
** Execute active_record_doctor:setup
** Execute active_record_doctor
rake aborted!
NoMethodError: undefined method `active_record' for nil (NoMethodError)

                [[association.source_reflection.active_record], "join"]
                                               ^^^^^^^^^^^^^^
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/incorrect_dependent_option.rb:88:in `block (2 levels) in detect'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:318:in `block (3 levels) in each_association'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/logger/dummy.rb:7:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:96:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:317:in `block (2 levels) in each_association'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:304:in `each'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:304:in `block in each_association'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/logger/dummy.rb:7:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:96:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:297:in `each_association'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/incorrect_dependent_option.rb:55:in `block in detect'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:183:in `block (3 levels) in each_model'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/logger/dummy.rb:7:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:96:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:182:in `block (2 levels) in each_model'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:169:in `each'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:169:in `block in each_model'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/logger/dummy.rb:7:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:96:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:168:in `each_model'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/incorrect_dependent_option.rb:54:in `detect'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:53:in `block in run'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/logger/dummy.rb:7:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:96:in `log'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:49:in `run'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/detectors/base.rb:17:in `run'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/runner.rb:16:in `block in run_one'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/errors.rb:5:in `handle_exception'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/runner.rb:15:in `run_one'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/runner.rb:31:in `block in run_all'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/runner.rb:30:in `each'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/runner.rb:30:in `run_all'
/Users/andy/.gem/ruby/3.3.4/gems/active_record_doctor-1.14.0/lib/active_record_doctor/rake/task.rb:60:in `block in define'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:281:in `block in execute'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:281:in `each'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:281:in `execute'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:219:in `block in invoke_with_call_chain'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:199:in `synchronize'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:199:in `invoke_with_call_chain'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/task.rb:188:in `invoke'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:188:in `invoke_task'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:138:in `block (2 levels) in top_level'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:138:in `each'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:138:in `block in top_level'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:147:in `run_with_threads'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:132:in `top_level'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:83:in `block in run'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:214:in `standard_exception_handling'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/lib/rake/application.rb:80:in `run'
/Users/andy/.gem/ruby/3.3.4/gems/rake-13.2.1/exe/rake:27:in `<top (required)>'
/Users/andy/.gem/ruby/3.3.4/bin/rake:25:in `load'
/Users/andy/.gem/ruby/3.3.4/bin/rake:25:in `<top (required)>'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/cli/exec.rb:58:in `load'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/cli/exec.rb:58:in `kernel_load'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/cli/exec.rb:23:in `run'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/cli.rb:455:in `exec'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/vendor/thor/lib/thor/command.rb:28:in `run'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/vendor/thor/lib/thor/invocation.rb:127:in `invoke_command'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/vendor/thor/lib/thor.rb:527:in `dispatch'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/cli.rb:35:in `dispatch'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/vendor/thor/lib/thor/base.rb:584:in `start'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/cli.rb:29:in `start'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/exe/bundle:28:in `block in <top (required)>'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/lib/bundler/friendly_errors.rb:117:in `with_friendly_errors'
/Users/andy/.gem/ruby/3.3.4/gems/bundler-2.5.16/exe/bundle:20:in `<top (required)>'
/Users/andy/.gem/ruby/3.3.4/bin/bundle:25:in `load'
/Users/andy/.gem/ruby/3.3.4/bin/bundle:25:in `<main>'
Tasks: TOP => active_record_doctor

My code, including the wrongly named source

class ChangeRequest < ApplicationRecord
  has_many :approvals, class_name: "ChangeRequestApproval", inverse_of: :change_request, dependent: :delete_all
  has_many :approver, through: :approvals, source: :member # <-- :member is wrong


class ChangeRequestApproval < ApplicationRecord
  belongs_to :approver, class_name: "Member", inverse_of: :change_request_approvals
  belongs_to :change_request, class_name: "ChangeRequest", inverse_of: :approvals
  

class Member < ApplicationRecord
  has_many :change_request_approvals, class_name: "ChangeRequestApproval", inverse_of: :approver, dependent: :delete_all  
  has_many :approved_change_requests, through: :change_request_approvals, source: :change_request

After correcting the relation

class ChangeRequest < ApplicationRecord
  has_many :approvals, ...
  has_many :approver, through: :approvals, source: :approver # <-- :approver is correct

It worked again.

Next Steps

Would be great, if someone can find the motivation and time to rescue the error and instead put out a clear error message. 😅

@fatkodima
Copy link
Contributor

I think, this will be solved by #179

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