Rails -- use type column without STI?
Solution 1
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
Solution 2
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
.
Solution 3
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.
Solution 4
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!
Related videos on Youtube
Kvass
Updated on February 26, 2020Comments
-
Kvass about 4 years
I want to use a column called
type
without invoking Single Table Inheritance (STI) - I just wanttype
to be a normal column that holds aString
.How can I do this without having Rails expecting me to have single table inheritance and throwing an exception of
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.
?Any ideas on how to do this?
-
Kvass over 12 yearsdo i need to actually create said column in my database?
-
Jon about 12 yearsThank you, this worked. A framework should NEVER!!!!! EVER!!!! dictate what a table field can't be named. That's supper bad for legacy data sets.
-
mu is too short about 12 years@Jon: Rails doesn't really care about legacy data or playing nice with others, Rails has too much attitude for that. You can make it behave itself with some effort but you always end up fighting a bit if you need to do something that Rails hasn't planned for (which unfortunately includes a lot of basic database concepts). OTOH, I'm a professional heretic so other Rails people will certainly be upset with me for pointing out the ideological problems :)
-
curot almost 12 yearsI think the idea is that Rails/Ruby prefer convention over configuration, so they try to optimize it for the use cases that they feel are correct.
-
Batkins over 11 yearsActually, it appears as though that changed in
rails 3.2
. According to apidock: 'This method is deprecated or moved on the latest stable version. The last existing version (v3.1.0) is shown here.' Thanks for the tip though! -
Valentin Nemcev over 11 yearsIt was deprecated in 3.1 and removed in 3.2, I think
-
lulalala about 11 years@Batkins The
inheritance_column
reader is moved (hence "deprecated or moved" notice). The use of setting theinheritance_column
instance variable directly is intended and is not deprecated. -
Benj almost 9 yearsSimpler version:
class MyModel < ActiveRecord::Base
self.inheritance_column = nil
end
. Reference: apidock.com/rails/ActiveRecord/ModelSchema/ClassMethods/… -
Benj almost 9 yearsWorks for me in rails 4.2.2. Perhaps you did not restart the server or spring after doing the change?
-
Benj almost 9 yearsAnd other users might find useful the simpler version I commented. As for the reload issue, I'm not expert but it would make sense to me to have a class property not automatically reloaded without unloading and reloading the class definition.
-
Benj almost 9 yearsI don't understand your reaction, I'm just trying to give a useful addition to your answer. Why are you feeling offended? I come in peace
-
John Bachir almost 7 yearsWorked in rails 5.1
-
Alexander Popov over 6 yearsOr better yet - in ApplicationRecord.
-
Joshua Pinter about 6 years@Benj Looks like they deleted whatever comment(s) you're referring to so now it just looks like you're arguing with yourself. ;)