2017-07-08 26 views
1

STIは特定の条件下で動作するはずです。アクティブレコードSTIが混乱しています

モデル(簡体字):(簡体字)

class Order < ApplicationRecord 
    has_many :items, class_name: 'OrderItem', inverse_of: :order 
end 

class OrderItem < ApplicationRecord 
    belongs_to :order, inverse_of: :items 
    has_one :spec, inverse_of: :order_item 
end 

class Spec < ApplicationRecord 
    belongs_to :order_item, inverse_of: :spec 
end 

class FooSpec < Spec 
end 

class BarSpec < Spec 
end 

スキーマ:私は私のGraphQLサーバ内のn + 1つの問題を回避するためにActiveRecord::Associations::Preloaderを使用してい

create_table "specs", force: :cascade do |t| 
    t.string "type", null: false 
    t.bigint "order_item_id", null: false 
    ... 
end 

。私はいくつかのSTIエラーを取得し始めました。コンソールから

、これは正常に動作してFooSpecまたはBarSpecを返します。

、これと同じ
Order.includes(items: :spec).first.items.first.spec 

Order.includes(:items).first.items.includes(:spec).first.spec 

そして、あまりにもこの:しかし

ActiveRecord::Associations::Preloader.new 
    .preload(Order.all, :items).first.owners.first.items.first.spec 

、この:

ActiveRecord::Associations::Preloader.new.preload(Order.all, items: :spec) 

そして、この:

ActiveRecord::Associations::Preloader.new 
    .preload(Order.all.map{|o| o.items}.flatten, :spec) 

レイズエラー:

ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'FooSpec'. This error is raised because the column 'type' is reserved for storing the class in case of inheritance. Please rename this column if you didn't intend it to be used for storing the inheritance class or overwrite Spec.inheritance_column to use another column for that information.

は時々私はアプリからわずかに異なるエラーを取得していますが、私は、コンソールでそれを再現することはできません。

ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: FooSpec is not a subclass of Spec)

ええと...ご覧のとおり、FooSpecは、間違いなくのサブクラスです。これらのエラーは通常、属性としてtypeを使用し、STIディスクリミネータではないことをActiveRecordに伝えていないことを意味します。ここではそうではありません。アイデア?

答えて

0

犯人が見つかりました。私はこれを持っていた:

class FooSpec < Spec 
    validates :my_field, inclusion: {in: MyClass::CHOICES} 
end 

私はこれにそれを変更した場合、問題は姿を消した:

class FooSpec < Spec 
    validates :my_field, inclusion: {in: -> (_instance) {MyClass::CHOICES}} 
end 

私は理由を理解していません。 MyClass::CHOICESは配列を保持する単純な定数です。クラスはclassy_enumです。

class MyClass < MyClassyEnum 
    CHOICES = %w[ 
    choiceOne 
    choiceTwo 
    ].freeze 
    ... 
end 
関連する問題