まとめ・エラー
アプリケーションのさまざまな場所でこのエラーが発生しています。
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 クラスが新しいクラス識別子を取得しています。ずさんな要求が原因であるという噂を聞いたことがあります。Company モデルで独自の require を行っているわけではありませんが、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
実際の質問
この問題が発生する理由と、何らかの方法で回避できるかどうかを知りたいと思っています。
原則として、例外が何を意味するかを知っています。回避方法が知りたいです。
特に、私が何らかの形で問題を引き起こしたのか、それとも宝石が原因なのかを知りたいです。その場合、何らかの方法で宝石を修正できるかどうかを知りたいです。
ご回答ありがとうございます。