摘要/错误
我在应用程序的不同位置收到此错误:
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'
控制器
控制器看起来像这样,但问题可能发生在使用 Company 模型保存或更新另一个模型的任何时候:
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。
提前感谢您的任何回答。