Skip to content

Database-level Multitable Inheritance for Rails

License

Notifications You must be signed in to change notification settings

talho/pin_cushion

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PinCushion
==========

Pin Cushion adds true Multiple Table Inheritance via a simple ActiveRecord::Migration command that is totally agnostic to ActiveRecord.

Pin Cushion was inspired by CITIEsForRAILS http://altrabio.github.com/CITIEsForRAILS/.  Unfortunately the majority of MTI solutions have some compatibility issues and are potentially sensitive to future changes in ActiveRecord.  Pin Cushion works almost entirely at the database level using views and some advanced database trigger features for INSERT/UPDATE/DELETE commands.

Pin Cushion currently only supports single-level multi-table inheritance though multi-level multi-table inheritance shouldn't be too difficult to add at a future date.  Pin Cushion currently only supports PostgreSQL since PostgreSQL allows the interception of INSERT/UPDATE/DELETE calls to overriding triggers (i.e. rules).  Although MySQL supports triggers, it is unknown at this time if it can override INSERT/UPDATE/DELETE calls to the view without throwing an error back to ActiveRecord.  Oracle should also be able to support these capabilities and hopefully someone who is interested in this solution for their Oracle tables will help add that in.  Pin Cushion would likely not support NoSQL solutions which is typically fine since Pin Cushion addresses designs more likely seen in relational systems.

It is recommended that a polymorphic association be used for any models that want to make use of your child model.  This will coincide with what is required in a Single Table Inheritance (STI) ActiveRecord solution.  The inheritance_column by default is 'user_type' where the parent class is called User.

Example
=======

For an already created Rails example using Pin Cushion see https://github.com/Dishwasha/pin_cushion_example

# Parent Table ActiveRecord Migration
CreateParentTable < ActiveRecord::Migration
  def self.up
    create_table :users do |t|
      t.string, :givenname
      t.string, :surname
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

# Child Table ActiveRecord Migration
CreateChildTable < ActiveRecord::Migration
  def self.up
    create_table :email_users, :id => false  do |t|
      t.string, :email
      t.integer, :user_id
    end

    # Here is the simple to use declaration to create all the multiple table inheritance structures and functions in the database
    CreateMTIFor(EmailUser)
  end

  def self.down
    DropMTIFor(EmailUser)
    drop_table :email_users
  end
end


# The parent class
class User < ActiveRecord::Base
  acts_as_MTI
end

# The child class
# A view is created by Pin Cushion with the intended table name prefixed with view_
# This is simple enough to not warrant an "acts_as_..." mixin
class EmailUser < User
  acts_as_MTI
end

After migrations are run, the two tables should look like one under the child model:

> user = EmailUser.create(:givenname => "Ethan", :surname => "Waldo", :email => "[email protected]")
=> #<EmailUser id: 1, givenname: "Ethan", surname: "Waldo", email: "[email protected]", created_at: "2011-03-16 22:51:19", updated_at: "2011-03-16 22:51:21">

> EmailUser.first
=> #<EmailUser id: 1, givenname: "Ethan", surname: "Waldo", email: "[email protected]", created_at: "2011-03-16 22:51:19", updated_at: "2011-03-16 22:51:21">

> User.first
=> #<User id: 1, givenname: "Ethan", surname: "Waldo", type: "EmailUser", created_at: "2011-03-16 22:51:19", updated_at: "2011-03-16 22:51:21">

> user.surname = "Weirdo"
=> "Weirdo"

> user.save
=> true

> EmailUser.first
=> #<EmailUser id: 1, givenname: "Ethan", surname: "Weirdo", email: "[email protected]", created_at: "2011-03-16 22:51:19", updated_at: "2011-03-16 22:51:47">

> user.destroy
=> #<EmailUser id: 1, givenname: "Ethan", surname: "Weirdo", email: "[email protected]", created_at: "2011-03-16 22:51:19", updated_at: "2011-03-16 22:51:47">

> EmailUser.first
=> nil

> User.first
=> nil

Copyright (c) 2011 Ethan Waldo, released under the MIT license

About

Database-level Multitable Inheritance for Rails

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Ruby 100.0%