Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails: Invalid single-table inheritance type error

So, I am working on migrating this php site with an existing database which I cannot change over to Rails. There is a table: Quotes with a column named type. Whenever I try and create a model of this and set the type, it tells me the following error:

ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: HOME is not a subclass of Quotes)

I don't understand why it thinks its inheriting because it's not supposed to. My create method looks like this:

quote = Quotes.create(
  agent_id: agent.id,
  client_id: client.id,
  type: 'HOME',
  status: 0,
  date_created: DateTime.now 
)

If I comment out the type, everything works fine. But with the Type it errors.

like image 798
Blaine Kasten Avatar asked Aug 14 '13 22:08

Blaine Kasten


People also ask

What is single-table inheritance in rails?

Single-table inheritance (STI) is the practice of storing multiple types of values in the same table, where each record includes a field indicating its type, and the table includes a column for every field of all the types it stores.

How does the single-table inheritance work?

In Single-Table Inheritance (STI), many subclasses inherit from one superclass with all the data in the same table in the database. The superclass has a “type” column to determine which subclass an object belongs to. In a polymorphic association, one model “belongs to” several other models using a single association.

What is a standard prerequisite for implementing single-table inheritance?

To get started with STI from a database perspective, all you need to do is add a field called “type” to the table. Rails takes this type field and applies the name of the sub-classes that inherit from the class for which the table is named as the value for a row of data.


2 Answers

I resolved this by setting the models inheritance_column to nil. Active Record Models can inherit from a table through the attribute :type, setting the inheritance_column to nil removes that attribute allowing you to have a database column named type

class Quote < ActiveRecord::Base
    self.inheritance_column = nil
end
like image 62
Blaine Kasten Avatar answered Oct 21 '22 18:10

Blaine Kasten


I hate having potential gotchas deep in the code especially in the intial processes like generating a model. Better to just change the reserved word to something else and free yourself up to take advantage of inheritance column later if the need comes up. A cleaner solution is listed here -> rename a database column name using migration

It reads;

  1. Execute $> rails generate migration ChangeColumnName where, ChangeColumnName is the name of our migration. This can be any name.
  2. Now, edit the generated migration file at db/migrate/_change_column_name.rb

    class ChangeColumnName < ActiveRecord::Migration
    def change
    rename_column :table_name, :old_column, :new_column
    end
    end
    
  3. $> rake db:migrate

You will have to edit controller and view files e.g. if the model name is Product then you will likely edit these files

  1. /app/views/products/_form.html.erb
  2. /app/views/products/show.html.erb
  3. /app/controllers/products_controller.erb
  4. /app/views/products/index.html.erb
like image 25
Ezeilo Uchenna Avatar answered Oct 21 '22 19:10

Ezeilo Uchenna