Skip to content

A library implemented Class Table Inheritance on ActiveRecord.

License

Notifications You must be signed in to change notification settings

productionap/activerecord-cti

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ActiveRecord::Cti

ActiveRecord-Cti is a library implemented Class Table Inheritance on Ruby on Rails. Class Table Inheritance (CTI) is useful under the circumstances that an ActiveRecord object is in multiple positions or has multiple roles, and you want to describe it's structure on the database. For example, one person may be a player and a coach in a soccer team.

Why use activerecord-cti ?

In ActiveRecord, Single Table Inheritance(STI) is implemented as a method of how to express inheritance model on database. Class Table Inheritance (CTI) has more powerful and flexible expressiveness for inheritance model on database than it of STI.

For Example, Suppose you want to describe the following class structure on database.

Class Diagram

But STI has a disadvantage that it is not possible to represent one record as an object of two different models at the same time.

people talbe (STI)

id type name birth_year position_name license_name
1 Player Ryan Giggs 1973 midfielder
2 Coach Ryan Giggs 1973 UEFA Pro

As mentiond above, for expressing two Person's subclasses objects, which are Player and Coach, you have to insert two records into people table in STI. It is cursed that the contents of name and birth_year columns are duplicated and position_name and license_name columns are sparse.

CTI can solve these problems by using multiple related tables like shown below, literally for class table inheritance.

ER Diagram

Installation

To install activerecord-cti on Rails, put this line in your Gemfile:

gem 'activerecord-cti'

And then execute bundle install

$ bundle install

How to use

Preparation

First of all, generate the files of models you want to apply CTI to, and execute migration.

$ rails g model Person name:string birth_year:integer
$ rails g model Player person_id:integer position_name:string 
$ rails g model Coach person_id:integer licence_name:string
$ rake db:migrate

Next, add the following line into Person model, which is base class.

class Person < ApplicationRecord
  include ActiveRecord::Cti::BaseClass #added
end

By this mix-in, Person model is configured as base class in CTI, and automatically becomes abstract class as well.

And then, rewrite files of subclass models for inheriting base class.

class Player < Person
end
class Coach < Person
end

Coding

To save data of Ryan Giggs as a football player, describe following:

player = Player.new(
  name: 'Ryan Giggs',
  birth_year: 1973,
  position_name: 'midfielder'
)
player.save

So that his data is automatically split into two related tables.

MariaDB> SELECT * FROM people limit 1;
+----+----------------+------------+
| id | name           | birth_year |
+----+----------------+------------+
|  1 | Ryan Giggs     | 1973       |
+----+----------------+------------+

MariaDB> SELECT * FROM players limit 1;
+----+----------------+---------------+
| id | person_id      | position_name |
+----+----------------+---------------+
|  1 | 1              | midfielder    |
+----+----------------+---------------+

Then, Ryan Giggs started coaching at Manchester United in 2013 as well as being a player. To save the data of Giggs as a coach to DB, describe following:

player = Player.find_by(name: 'Ryan Giggs')
coach = player.to_coach(licence_name: 'UEFA Pro')
coach.save

So that his data is newly inserted into only coaches table.

MariaDB> SELECT * FROM coaches limit 1;
+----+----------------+--------------+
| id | person_id      | licence_name |
+----+----------------+--------------+
|  1 | 1              | UEFA Pro     |
+----+----------------+--------------+

To get Ryan Giggs's Data as a coach, describe following:

Coach.find_by_name('Ryan Giggs') #<Coach id: 1, name: "Ryan Giggs", licence_name: 'UEFA Pro'>

Like this, pserson_id, which coaches table has as foreign_key reffered to base class object, is concealed.

License

The gem is available as open source under the terms of the MIT License.

About

A library implemented Class Table Inheritance on ActiveRecord.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Ruby 82.1%
  • HTML 14.0%
  • JavaScript 2.0%
  • CSS 1.9%