簡體   English   中英

ActiveRecord::SubclassNotFound:單表繼承機制定位子類失敗

[英]ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass

我是 Rails 的新手。
我有兩個模型類別產品如下:-

class Category < ActiveRecord::Base
 attr_accessible :type

 has_many :products
end

class Product < ActiveRecord::Base
 attr_accessible :category_id, :color, :price, :title

 belongs_to :category
end

我的schema.rb如下:-

ActiveRecord::Schema.define(:version => 20130725220046) do

create_table "categories", :force => true do |t|
    t.string   "type"
    t.datetime "created_at", :null => false
    t.datetime "updated_at", :null => false
  end

  create_table "products", :force => true do |t|
    t.integer  "category_id"
    t.decimal  "price",       :precision => 10, :scale => 0
    t.string   "title"
    t.string   "color"
    t.datetime "created_at",                                 :null => false
    t.datetime "updated_at",                                 :null => false
  end

end

在 Rails 控制台中,我使用Product.create命令創建了兩個產品和兩個產品

[#<Product id: 1, category_id: 1, price: 500, title: "shirt", color: "blue", `created_at: "2013-07-25 22:04:54", updated_at: "2013-07-25 22:04:54">, #<Product id: 2, category_id: 1, price: 600, title: "tees", color: "black", created_at: "2013-07-25 22:05:17", updated_at: "2013-07-25 22:05:17">]`  

並在控制台中使用Category.create命令創建了兩個類別

<Category id: 1, type: "clothing", created_at: "2013-07-25 22:03:54", updated_at: "2013-07-25 22:03:54"><Category id: 2, type: "footwear", created_at: "2013-07-25 22:04:02", updated_at: "2013-07-25 22:04:02">  

現在, Product.all工作正常,但Category.all給出

ActiveRecord::SubclassNotFound: 單表繼承機制無法定位子類:'clothing'。 引發此錯誤是因為列“類型”保留用於在繼承的情況下存儲類。 如果您不打算將此列用於存儲繼承類或覆蓋 Category.inheritance_column 以使用另一列存儲該信息,請重命名此列。

里面有什么問題? 我想在類別和產品之間建立關系,例如
一個類別有_許多產品並且產品屬於_一個類別。

type是受限制的詞,您不能將其用作 ActiveRecord 模型中的列名(除非您正在執行 STI)。

嘗試使用inheritance_column,然后類型將不再被保留:

class Category < ActiveRecord::Base
 self.inheritance_column = :foo
 attr_accessible :type

 has_many :products
end

class Product < ActiveRecord::Base
 attr_accessible :category_id, :color, :price, :title

 belongs_to :category
end

剛剛在嘗試使用這種type保留字找到我自己的問題的解決方案時遇到了這篇文章,所以也許這可以幫助其他人。

更改列的名稱對我來說不是一個簡單的解決方案,因為我正在處理一個從 mongodb 遷移到活動記錄的現有完整系統。

我發現將self.inheritance_column = :_type_disabled添加到具有違規列名的模型中修復了我在此處找到的錯誤。

禁用 STI

我必須添加“self.inheritance_column”而不是簡單的“inheritance_column”才能使其工作。 代碼示例

class MyModel < ActiveRecord::Base # 禁用 STI
self.inheritance_column = :_type_disabled end

我知道我們沒有使用任何繼承,所以我認為這樣做對我來說很好,但我不知道可能會因此產生什么其他影響。 如果其他人對此有任何意見,我很想知道。

如果您可以更改列名並避免這樣做,那么我確信這是一個更好的解決方案。

如果有人真的試圖取消 STI,請嘗試添加一個從父級繼承的新類,有問題的錯誤消息應該會消失。

class YourSubclass < Category
end

如果你發現這個問題是因為你遇到了同樣的錯誤,而你實際上是在使用 Rails STI,但是因為你試圖重命名繼承的子類而得到錯誤,這可能是因為你的type列中有舊數據而忘記更新它. 那么這個 rake 任務可能會有所幫助:

update_category_type_column_with_new_subclass_names.rake

# This will be run when running `rake categories:update_type_column_with_new_subclass_names`
namespace :categories do
  desc 'Run through the categories with values in the type column and rename those according to the new subclass names: CategorySubclass1 -> CategorySubclass1NewName, CategorySubclass2 -> CategorySubclass2NewName, and CategorySubclass3 -> CategorySubclass3NewName . Run this rake task without arguments.'
  task update_type_column_with_new_subclass_names: :environment do
    Category.inheritance_column = :_type_disabled # to avoid getting error when using the type column: "ActiveRecord::SubclassNotFound: The single-table inheritance mechanism failed to locate the subclass: 'CategorySubclass1'"
    categories = Category.where("type <> '' AND type IS NOT NULL")
    categories.each do |a|
        begin
            case a.type
            when 'CategorySubclass1'
                a.type = 'CategorySubclass1NewName'
                a.save!
            when 'CategorySubclass2'
                a.type = 'CategorySubclass2NewName'
                a.save!
            when 'CategorySubclass3'
                a.type = 'CategorySubclass3NewName'
                a.save!
            end
        rescue StandardError => e
            puts '---'
            puts 'Error trying to set :type for category with :'
            puts 'id and url: '
            puts ' ' + a.id.to_s
            puts ' ' + a.type
            puts 'Error message: '
            puts e.message
            puts '---'
        end
    end
    Category.inheritance_column = :type # switch on the Rails STI after you've made your updates to the DB columns
  end
end

如果當前 AR 模型未使用 STI,則可以在模型中設置self.inheritance_column = :_sti_disabled (或其他名稱)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM