Invalid single-table inheritance type: Rails

inheritance, ruby-on-rails, ruby-on-rails-4

Solution

You should not use the `type` keyword as the column name because it is a reserved word for ActiveRecord.

But if you really want to use it, for any reason (like if you don't have control on the DB structure), here is what you should do:

First, make sure your Movie model inherits from the (false-)"abstract" model Product:

class Product < ActiveRecord::Base
  TYPES = %w( Movie )
  before_save :set_type
  validates :type, presence: true, :inclusion => { :in => TYPES }

  def set_type
    raiser "You must override this method in each model inheriting from Product!"
  end

  # ...

class Movie < Product

  def set_type # If you don't implement this method, an error will be raised
    self.type = 'Movie'
  end

And then in your ProductsController you can manage (CRUD) all kind of products.

To add a new type of product: you just have to define a new Model inheriting from Product, implement it's set_type method and add the type in the product's Constant:

class Book < Product
  def set_type
    self.type = 'Book'
  end
  #...

class Product < ActiveRecord::Base
  TYPES = %w( Movie Book )

Problem

I'm getting this error when trying to create a new Product in my Rails application. Invalid single-table inheritance type: Movie is not a subclass of Product How can I resolve this? controller ``` class ProductsController < ApplicationController before_action :set_product, only: [:show, :edit, :update, :destroy] # GET /products # GET /products.json def index @products = Product.all end # GET /products/1 # GET /products/1.json def show end # GET /products/new def new @product = Product.new end # GET /products/1/edit def edit end # POST /products # POST /products.json def create @product = Product.new(product_params) respond_to do |format| if @product.save format.html { redirect_to @product, notice: 'Product was successfully created.' } format.json { render action: 'show', status: :created, location: @product } else format.html { render action: 'new' } format.json { render json: @product.errors, status: :unprocessable_entity } end end end # PATCH/PUT /products/1 # PATCH/PUT /products/1.json def update respond_to do |format| if @product.update(product_params) format.html { redirect_to @product, notice: 'Product was successfully updated.' } format.json { head :no_content } else format.html { render action: 'edit' } format.json { render json: @product.errors, status: :unprocessable_entity } end end end # DELETE /products/1 # DELETE /products/1.json def destroy @product.destroy respond_to do |format| format.html { redirect_to products_url } format.json { head :no_content } end end private # Use callbacks to share common setup or constraints between actions. def set_product @product = Product.find(params[:id]) end # Never trust parameters from the scary internet, only allow the white list through. def product_params params.require(:product).permit(:title, :artist, :type, :release_date, :category, :publisher, :format, :description, :sale_price, :rental_price) end end ``` migration ``` class CreateProducts < ActiveRecord::Migration def change create_table :products do |t| t.string :title t.string :artist t.string :type t.date :release_date t.string :category t.string :publisher t.string :format t.text :description t.decimal :sale_price t.decimal :rental_price t.timestamps end end end ```

Original source