Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extend Model in Rails

I'm trying to extend a model in rails.

Model User uses table users in database with field :username, :password.

class User < ActiveRecord::Base
end

Model SuperUser uses table super_users in database with fields :user_id, :name:

class SuperUser < ActiveRecord::Base
 belongs_to :user
end

I would like the SuperUser to be an extension of User so as to be able to do this :

SuperUser.create(:name => "foo", :username => "bar", :password => "foobar")

or when I fetch data to get something like this

> s = SuperUser.find 1
> s.username
> "bar"    

Has anyone any idea how I can do this?

like image 755
skalogirou Avatar asked Sep 24 '15 17:09

skalogirou


2 Answers

You need to consider two possible patterns of extending your models. One of them, Single Table Inheritance is built into Rails and is well documented. The other pattern, the Multi Table Inheritance, which is surprisingly less welcomed in Rails. You need to implement it yourself or use less popular gem for it.

One of the reasons why, I think, MTI is not well supported in Rails is related to performance. For example, even simple User.find 1 should be a lookup in two tables.

What you ask in your question (having two tables) is MTI. But why not STI in this simple case? Are User and SuperUser as deviated from each other that you worry about saving space and using two separate tables for them?

For me it looks like going with a single users table, and adding type column to it.

add_column :users, :type, :string

Now:

class User < ActiveRecord::Base
end

class SuperUser < User
end

and it just works.

like image 184
dimakura Avatar answered Sep 16 '22 15:09

dimakura


You'd want to use either Single Table Inheritance (STI) or Multiple Table Inheritance (MTI). This is not as complicated as it may seem at first. You can read about it here

like image 41
davidrac Avatar answered Sep 17 '22 15:09

davidrac