【问题标题】:What does has_many_polymorphs mean by "Referential integrity violation"?“违反参照完整性”的 has_many_polymorphs 是什么意思?
【发布时间】:2009-08-05 20:39:39
【问题描述】:

我在Candidate 和许多不同类型的事件之间有一个has_many_polymorphs 关系。特别是,Candidate 在创建时会创建 Created 事件。

class Candidate < ActiveRecord::Base
  has_many_polymorphs :events, :through => :candidate_events,
                               :from => Event::Base.included_in_classes.map { |klass|
                                 klass.to_s.underscore.pluralize.to_sym
                               })
  after_validation_on_create :create_created_event

  private
  def create_creation_event
    Event::Created.create!(:candidate => self, :creator => creator)
  end
end

class CandidateEvent < ActiveRecord::Base
  belongs_to :candidate
  belongs_to :event, :polymorphic => true
end

module Event::Base
  ...
end

class Event::Created < ActiveRecord::Base
  include Event::Base
  validates_presence_of :creator
end

当我运行单元测试时,一切都很好。当我运行我的功能测试时,一切都很好。当我运行我的集成(Cucumber)测试时,一切都很好。当我在生产中运行时,一切都很好。当我尝试在开发模式下运行(打开类重新加载)时,我得到了

Referential integrity violation; child <Event::Created:1> was not found for :events.
Expected record['candidate_events.event_id'] (1) to be equal to record['created_events.id'] ().
  {
    "candidate_events.event_type"=>"Event::Created",
    "candidate_events.created_at"=>"2009-08-05 20:28:31",
    "candidate_events.updated_at"=>"2009-08-05 20:28:31",
    "candidate_events.candidate_id"=>"1",
    "candidate_events.event_id"=>"1",
    "candidate_events.id"=>"1"
  }

在同一(开发)环境中运行 script/console 我看到 Event::Created 对象与 CandidateEvent 交叉引用模型具有适当的关系。

发生了什么事?

【问题讨论】:

  • 您能否向我们展示一些针对您开发数据库中这些表中相关行的 sql 查询的结果?
  • 他们真的直截了当。我只有一行,每个都有正确的外键(都是“1”)

标签: ruby-on-rails ruby activerecord has-many-polymorphs


【解决方案1】:

我们能否确定 Event::Base.included_in_classes 在类重新加载时返回正确的类?这种技巧不是依赖于加载顺序吗?即也许 Event::Created 还没有包含 Event::Base?

【讨论】:

  • 有趣的问题。我设置了一些保护代码来防止这些类被定义两次,因为我得到了重复的 before_save 钩子。我会试着把警卫放在钩子周围!
  • 嗯,不是这样。我已将&lt;% raise Event::Created.included_modules.inspect %&gt; 放在导致问题的视图顶部,结果确实 包括Event::Base
  • 我什至扔了几行“require event”,并在 event.rb 的底部放置了一个“需要事件/已创建”(以及所有其他)。依然没有。不过,我仍然被这种思路所吸引。
  • 啊哈!如果我在 'require event' 之后放置一个跟踪语句( puts "#{'=' * 40}\n#{Event::Base.included_in_classes.inspect}\n#{'=' * 40}")在candidate.rb 的顶部我得到“[]”作为结果!
  • 不错。你也可以在 has_many_polymorphs 中尝试一些热敲击动作。事件::Base.included_in_classes.tap{|c| p c}.map{|... 我需要进一步了解类重新加载的真正含义。
猜你喜欢
  • 1970-01-01
  • 2019-07-25
  • 1970-01-01
  • 1970-01-01
  • 2018-12-28
  • 1970-01-01
  • 2017-12-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多