ActiveRecord :: ConfigurationError - 未找到名为“whatever”的关联

时间:2014-05-29 18:17:41

标签: ruby-on-rails-3 activerecord polymorphic-associations rails-engines

我有一个复杂的情况,我正在开发一个Rails 3引擎,我只是间歇地得到标题中的错误。这是堆栈跟踪:

ActiveRecord::ConfigurationError - Association named 'whatever' was not found; perhaps you misspelled it?:
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:150:in `block in records_by_reflection'
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:146:in `records_by_reflection'
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:139:in `grouped_records'
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:130:in `preload_one'
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:109:in `preload'
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:98:in `block in run'
  activerecord (3.2.18) lib/active_record/associations/preloader.rb:98:in `run'
  activerecord (3.2.18) lib/active_record/relation.rb:181:in `block in exec_queries'
  activerecord (3.2.18) lib/active_record/relation.rb:180:in `exec_queries'
  activerecord (3.2.18) lib/active_record/relation.rb:160:in `block in to_a'
  activerecord (3.2.18) lib/active_record/explain.rb:41:in `logging_query_plan'
  activerecord (3.2.18) lib/active_record/relation.rb:159:in `to_a'
  activerecord (3.2.18) lib/active_record/relation/delegation.rb:39:in `+'
  /Users/me/src/appointment_engine/app/controllers/appointment_engine/appointments_controller.rb:42:in `block (3 levels) in index'
  /Users/me/src/appointment_engine/app/controllers/appointment_engine/appointments_controller.rb:41:in `block (2 levels) in index'
  actionpack (3.2.18) lib/action_controller/metal/mime_responds.rb:196:in `respond_to'
  /Users/me/src/appointment_engine/app/controllers/appointment_engine/appointments_controller.rb:12:in `index'

总结:引擎中有一个名为Appointment的模型,它与has_many :through多态关联到主机应用的User模型(这是一个要求,因为我们还关联到另一个模型)。以下是has_many

中的Appointment声明
class Appointment < ActiveRecord::Base
  has_many :scheduleables,
    through: :appointments_scheduleables,
    source_type: KAE.scheduleable_class.name
  has_many :schedulers,
    through: :appointments_schedulers,
    source_type: KAE.scheduler_class.name
end

我遇到了第一个问题;我需要在:source_type多态关联上设置has_many :through(没有它就行不通),为此我需要知道关联模型的类,但是当我的引擎Appointment时模型加载它是在主机应用程序的User模型加载之前执行的,因此我的引擎模块KAE尚未收到KAE.scheduleable_class的值。

以下是KAE收到该值的方式:

# in host app
class User < ActiveRecord::Base
  acts_as_scheduler
end

我将acts_as_scheduler写为AR mixin,它会将has_many :through关联声明为Appointment

我的第一次尝试解决这个问题:我将Appointment的{​​{1}}声明放在铁路内的钩子中:

has_many

好的,现在有效,我等到主机应用程序完全加载,现在我有ActiveSupport.on_load :after_initialize do KAE::Appointment.class_eval do has_many :scheduleables, through: :appointments_scheduleables, source_type: KAE.scheduleable_class.name has_many :schedulers, through: :appointments_schedulers, source_type: KAE.scheduler_class.name end end KAE.scheduleable_class的值,非常好。

除了我间歇性地收到标题中的错误!

我可以正常启动,使用该应用程序一段时间(10-30分钟),然后出于无处繁荣!我在KAE.scheduler_classrails serverthin下尝试过了。所有相同,所以它必须是一个应用程序/框架级错误。我查看活动记录预加载器类到堆栈跟踪顶部指向的位置:

unicorn

模型如何忘记它的某些关联?

所以现在我直接在# lib/active_record/associations/preloader.rb:150 def records_by_reflection(association) records.group_by do |record| reflection = record.class.reflections[association] unless reflection raise ActiveRecord::ConfigurationError, "Association named '#{association}' was not found; " \ "perhaps you misspelled it?" end reflection end end 模型中这样做,它似乎工作到目前为止,但它真的很难看:

Appointment

有人知道在Rails 3引擎中声明class Appointment < ActiveRecord::Base if KAE.scheduler_class && KAE.scheduleable_class has_many :scheduleables, through: :appointments_scheduleables, source_type: KAE.scheduleable_class.name has_many :schedulers, through: :appointments_schedulers, source_type: KAE.scheduler_class.name else binding.pry # TODO ActiveSupport.on_load :after_initialize do KAE::Appointment.class_eval do has_many :scheduleables, through: :appointments_scheduleables, source_type: KAE.scheduleable_class.name has_many :schedulers, through: :appointments_schedulers, source_type: KAE.scheduler_class.name end end end end 多态关联的更好方法吗?

我一直在研究像has_many :throughacts_as_taggable_on_steroids这样的开源项目,看看他们是如何进行关联的,但他们没有多态paper_trail

有人知道有这种关联的项目吗?

1 个答案:

答案 0 :(得分:0)

使用Rails自动加载+自动重新加载魔法加载排序可能很痛苦。在这些情况下,我只是让我的依赖更明确。我建议您尝试在主机中使用Rails的require_dependency以确保不会发生这种情况:

# in host app
require_dependency 'appointment'
class User < ActiveRecord::Base
  acts_as_scheduler
end

ActiveSupport的require版本也适用于开发环境的自动重新加载,这可能是您在处理应用程序时间歇性地遇到此问题的原因。