22

If I have a User and I want to make different types of users, say just normal users with only an email and subscribers who have a website field, how would I make subscribers inherit everything from Users with just an added field?

2 Answers2

26

You would need to create a table with all of the fields, as well as specify a type column. i.e

create_table :users do |t|
  t.string :email
  t.string :website
  t.string :type
end

Then you can have classes like

Class User < ActiveRecord::Base

Class Subscriber < User

A subscriber will inherit everything from the Users model. The type column is there so that you can distinguish from the different models. For instance using

Subscriber.all 

Will only get subscribers, where as if you did not use the 'type' column it would also find users too.

Kyle d'Oliveira
  • 6,382
  • 1
  • 27
  • 33
  • 21
    OP: This is called "Single Table Inheritance" or "STI". So Google that for more info on how it works if you need it. – Pavling Jun 21 '11 at 18:08
  • 5
    After doing quite a bit of googling on the topic, some also seem to prefer using polymorphic associations when the data differs between the models. This avoids having a single table with lots of null fields. I found this railscast helpful: http://railscasts.com/episodes/394-sti-and-polymorphic-associations. – rogerkk Mar 07 '13 at 13:06
  • What actual value should the type column have? – Michael Durrant Apr 21 '13 at 14:00
  • @MichaelDurrant Do you mean the contents in the DB? It'll be the name of the class that it refers to. So in the example, you would have the strings "User" and "Subscriber" as the values in the type field – Kyle d'Oliveira Apr 22 '13 at 16:28
  • @Olives I have value ```nil``` if "User" and ```Subscriber``` if Subscriber in type column – Pavel Kalashnikov Mar 09 '15 at 23:19
13

You want single table inheritance, described at the link by Alex Reisner. STI uses a single table to represent multiple models that inherit from a base model. In the Rails world, the database schema has a column which specifies the type of model represented by the row. Adding a column named type in a database migration has Rails infer the table uses STI, although the column can be an arbitrary name if you specify the name in the data model (see the class method 'inheritance_column'). Note that this makes type a reserved word.

Fred
  • 8,582
  • 1
  • 21
  • 27
  • 2
    That's broken. I guess correct link is [http://www.alexreisner.com/code/single-table-inheritance-in-rails](http://www.alexreisner.com/code/single-table-inheritance-in-rails) – Varinder Singh Jun 17 '13 at 13:39
  • While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Luke Nov 08 '15 at 22:49
  • 1
    @Luke: As long as "single table inheritance" is the answer, that's not exactly link-only. – Nathan Tuggy Nov 10 '15 at 01:24
  • @NathanTuggy As you'll see in Olives' answer, providing a simple example really is the preferred outcome here. – Luke Nov 10 '15 at 07:48