【发布时间】:2013-04-09 18:26:17
【问题描述】:
总结/错误
我在应用程序的不同位置收到此错误:
ActiveRecord::AssociationTypeMismatch in Settings::CompaniesController#show
Company(#70257861502120) expected, got Company(#70257861787700)
activerecord (3.2.11) lib/active_record/associations/association.rb:204:in `raise_on_type_mismatch'
activerecord (3.2.11) lib/active_record/associations/belongs_to_association.rb:6:in `replace'
activerecord (3.2.11) lib/active_record/associations/singular_association.rb:17:in `writer'
activerecord (3.2.11) lib/active_record/associations/builder/association.rb:51:in `block in define_writers'
activerecord (3.2.11) lib/active_record/attribute_assignment.rb:85:in `block in assign_attributes'
activerecord (3.2.11) lib/active_record/attribute_assignment.rb:78:in `each'
activerecord (3.2.11) lib/active_record/attribute_assignment.rb:78:in `assign_attributes'
activerecord (3.2.11) lib/active_record/base.rb:497:in `initialize'
app/controllers/settings/companies_controller.rb:4:in `new'
app/controllers/settings/companies_controller.rb:4:in `show'
控制器
控制器看起来像这样,但问题可能发生在使用公司模型保存或更新另一个模型的任何时候:
class Settings::CompaniesController < SettingsController
def show
@company = current_user.company
@classification = Classification.new(company: @company)
end
def update
end
end
事实/观察
一些事实和观察:
- 问题随机出现,但通常是在开发服务器运行一段时间后。
- 生产中不会出现此问题。
- 即使我没有对
Company模型进行任何更改,也会出现此问题。 - 问题通过重启服务器解决。
理论
据我了解,这是由于类的动态加载造成的。
Company 类在重新加载时以某种方式获得了新的类标识符。我听说它是由于草率的要求。在公司模型中我没有自己的要求,但我确实使用了active-record-postgres-hstore。
模型
这是Company 型号:
class Company < ActiveRecord::Base
serialize :preferences, ActiveRecord::Coders::Hstore
DEFAULT_PREFERENCES = {
require_review: false
}
has_many :users
has_many :challenges
has_many :ideas
has_many :criteria
has_many :classifications
attr_accessible :contact_email, :contact_name, :contact_phone, :email, :logotype_id, :name, :phone, :classifications_attributes, :criteria_attributes, :preferences
accepts_nested_attributes_for :criteria
accepts_nested_attributes_for :classifications
after_create :setup
before_save :set_slug
# Enables us to fetch the data from the preferences hash directly on the instance
# Example:
# company = Company.first
# company.preferences[:foo] = "bar"
# company.foo
# > "bar"
def method_missing(id, *args, &block)
indifferent_prefs = HashWithIndifferentAccess.new(preferences)
indifferent_defaults = HashWithIndifferentAccess.new(DEFAULT_PREFERENCES)
if indifferent_prefs.has_key? id.to_s
indifferent_prefs.fetch(id.to_s)
elsif indifferent_defaults.has_key? id.to_s
indifferent_defaults.fetch(id.to_s)
else
super
end
end
private
def setup
DefaultClassification.find_each do |c|
Classification.create_from_default(c, self)
end
DefaultCriterion.find_each do |c|
Criterion.create_from_default(c, self)
end
end
def set_slug
self.slug = self.name.parameterize
end
end
分类模型:
class Classification < ActiveRecord::Base
attr_accessible :description, :name, :company, :company_id
has_many :ideas
belongs_to :company
def to_s
name
end
end
实际问题
我真的很想知道为什么会出现这个问题,以及是否可以通过某种方式避免它。
原则上我知道异常意味着什么。我想知道如何避免它。
特别是,我想知道我是否以某种方式引起了问题,或者它是否是 gem,在这种情况下,我是否可以通过任何方式帮助修复 gem。
提前感谢您的任何回答。
【问题讨论】:
-
ActiveRecord::AssociationTypeMismatch出现when an object assigned to an association has an incorrect type。在您的情况下,您是associating company to classification。当您在它们之间定义关联时,这是正确的。但是您并没有在您的操作中保存对象。 -
是的,我知道异常意味着什么。关联是双向定义的,将添加编辑以反映这一点。关于这句话:“但你并没有在你的行动中保存对象”。我不保存它,因为我不想保存它。我正在为表单准备一个分类对象。
-
这也发生在我身上。分期和生产都很好,但在开发中它会在一段时间后中断。我们已经对此进行了几次测试(我们还尝试删除所有记录并创建新记录)
-
新的开始工作,但过了一会儿,他们突然返回错误的类型。实际上 - 我们的模型中有一个方法可以将序列化数据转换为具有无关访问的哈希。问题是,一段时间后,检索序列化列会产生一个字符串而不是预期的哈希。同样,这不会发生在生产/登台
标签: ruby-on-rails activerecord ruby-on-rails-3.2