Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Invalid single-table inheritance type .. is not a subclass of

I am trying to record each purchase a user makes through a many-to-many relationship between Users and Transactions and link them through a join table "transactuins_users". But I have two problems, first, I am required to supply the create! method with the object it is called upon's id, I thought that Rails was supposed to figure this out by itself given the association.

Furthermore, whenever I call the purchase method, I receive an error "Invalid single-table inheritance type: buy is not a subclass of Transaction"

class User < ActiveRecord::Base

  # Associations
  has_and_belongs_to_many :transactions

  def purchase(package)
    return false unless funds_available?(package) and !owns?(package)
      package.with_lock do

      # Makes transaction
      package.user_id = id
      package.save!
      withdraw(package.cost)

      # Records transaction
      values = {user_id: id, type: "buy", cost: package.cost}
      transactions.create values
    end
  end


class Transaction < ActiveRecord::Base

  # Associations 
  has_and_belongs_to_many :transactions

  # Validations
  validates :user_id, :cost, presence: true
like image 842
manis Avatar asked Mar 29 '14 15:03

manis


3 Answers

Active Record has certain schema conventions that is uses for different behaviors. One of these conventions is to use the column name "type" when you want to use single table inheritance in your models. It doesn't look like you intended to use STI, so I'd recommend just changing the name of the column to something else like "kind" or "category".

If you plan on having different behavior for the various types of transactions, you might want to consider using single table inheritance after all.

like image 145
Peter Brown Avatar answered Oct 13 '22 12:10

Peter Brown


Add self.inheritance_column = nil to your model. type is reserved. This will allow you to use it.

like image 30
DDDD Avatar answered Oct 13 '22 11:10

DDDD


I had the same error. You must have already solved it by now but in case someone else is looking for it, i had my field named as type, same as in the question.

The type is reserved word and used in inheritance. Hence, when you use type: "buy", it tries to look for buy model and expects the buy model to be inherited from User.

I'll share my logs for better understanding:

Parameters: {"step"=>{"type"=>"Email Template", "step_name"=>"Step name", "no_of_days"=>20, "cadence_id"=>nil, "email_template_id"=>nil}}

Completed 500 Internal Server Error in 238ms

ActiveRecord::SubclassNotFound (Invalid single-table inheritance type: Email Template is not a subclass of Step):
   app/controllers/steps_controller.rb:15:in `create'

If you still need to keep the field name as type, i believe adding self.inheritance_column = nil to the user model might help. Haven't tried. Though my recommendation would be to follow the rails convention and avoid it.

You can find more details here

Hope this helps someone. Cheers :)

like image 33
Aakanksha Avatar answered Oct 13 '22 12:10

Aakanksha