Rails ——使用不带 STI 的类型列?

我想使用一个名为 type的列而不调用单表继承(STI)-我只希望 type是一个包含 String的普通列。

如果 Rails 希望我只有一个表继承并抛出 The single-table inheritance mechanism failed to locate the subclass...This error is raised because the column 'type' is reserved for storing the class in case of inheritance.异常,我怎么能做到这一点呢?

有什么办法吗?

31711 次浏览

You can override the STI column name using set_inheritance_column:

class Pancakes < ActiveRecord::Base
set_inheritance_column 'something_you_will_not_use'
#...
end

So pick some column name that you won't use for anything and feed that to set_inheritance_column.


In newer versions of Rails you'd set inheritance_column to nil:

class Pancakes < ActiveRecord::Base
self.inheritance_column = nil
#...
end

In Rails 3.1 set_inheritance_column is deprecated, also you can just use nil as a name, like this:

class Pancakes < ActiveRecord::Base
self.inheritance_column = nil
#...
end

Rails 4.x

I encountered the problem in a Rails 4 app, but in Rails 4 the set_inheritance_column method does not exist at all so you can't use it.

The solution that worked for me was to disable the single table inheritance by overriding ActiveRecord’s inheritance_column method, like this:

class MyModel < ActiveRecord::Base


private


def self.inheritance_column
nil
end


end

Hope it helps!

I know this question is rather old and this deviates a bit from the question you are asking, but what I always do whenever I feel the urge to name a column type or something_type is I search for a synonym of type and use that instead:

Here are a couple alternatives: kind, sort, variety, category, set, genre, species, order etc.

If you want to do this for all models, you can stick this in an initializer.

ActiveSupport.on_load(:active_record) do
class ::ActiveRecord::Base
# disable STI to allow columns named "type"
self.inheritance_column = :_type_disabled
end
end