Ответ 1
type
- это ограниченное слово, вы не можете использовать его как имя столбца в моделях ActiveRecord (если вы не делаете STI).
Я новичок в 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: механизм наследования с одной таблицей не смог найти подкласс: "одежда". Эта ошибка возникает из-за того, что тип столбца зарезервирован для хранения класса в случае наследования. Переименуйте этот столбец, если вы не собираетесь использовать его для хранения класса наследования или перезаписать Category.inheritance_column, чтобы использовать другой столбец для этой информации.
Что там плохого? Я хочу установить отношения между категорией и продуктом, например, категория has_many продуктов и продуктов принадлежит к категории.
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
к модели с ошибочным именем столбца исправило ошибку, которую я нашел здесь.
Отключить ИППП
Мне пришлось добавить "self.inheritance_column", а не просто "inheritance_column", чтобы заставить это работать. Пример кода
Класс MyModel <ActiveRecord :: Base # отключить STI
self.inheritance_column =: _type_disabled end
Я знаю, что мы не используем какое-либо наследование, поэтому я думаю, что это нормально для меня, но я не знаю, какие другие последствия могут быть из-за этого. Если у кого-то еще есть мнения по этому поводу, мне было бы интересно узнать.
Если вы можете просто изменить имя столбца и избежать этого, я уверен, что это гораздо лучшее решение.
Если кто-то на самом деле пытается снять STI, попробуйте добавить новый класс, который наследуется от родителя, и соответствующее сообщение об ошибке должно исчезнуть.
class YourSubclass < Category
end
Если вы обнаружили этот вопрос, потому что столкнулись с той же ошибкой, и на самом деле используете Rails STI, но получили ошибку, потому что вы пытались переименовать унаследованные подклассы, это, вероятно, потому, что у вас есть старые данные в столбце type
и забыл обновить его. Тогда эта задача рейка может помочь:
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
Вы можете установить внутри своей модели self.inheritance_column = :sti_disabled
(или другое имя), если вы не используете STI для текущей модели AR