【问题标题】:Active Record STI ConfusedActive Record STI 困惑
【发布时间】:2017-07-08 17:50:04
【问题描述】:

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

架构(简化):

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

我正在使用ActiveRecord::Associations::Preloader 来避免我的 GraphQL 服务器中出现 n+1 问题。我开始遇到一些 STI 错误。

从控制台,这可以正常工作并返回 FooSpecBarSpec

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:单表继承机制 未能找到子类:'FooSpec'。引发此错误 因为列'type'保留用于存储类,以防万一 遗产。如果您不打算将其重命名,请重命名此列 用于存储继承类或覆盖 Spec.inheritance_column 为该信息使用另一列。

有时我会从应用程序中得到一个稍微不同的错误,但我无法在控制台中重现它:

ActiveRecord::SubclassNotFound(无效的单表继承类型: FooSpec 不是 Spec 的子类)

嗯...如您所见,FooSpec 绝对是Spec 的子类。这些错误通常意味着您使用type 作为属性并且没有告诉ActiveRecord 它不是STI 鉴别器。这不是这里的情况。想法?

【问题讨论】:

    标签: ruby-on-rails ruby activerecord


    【解决方案1】:

    我找到了罪魁祸首。我有这个:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2012-03-24
      • 1970-01-01
      相关资源
      最近更新 更多