Empty Eye

ActiveRecord based MTI gem powered by database views

Issues

  • No known issues major issues; has been successful within data structures of high complexity (MTI to MTI, MTI to STI to MTI relationships)
  • Not sure why but new mti instances have a id of zero; this has caused no problems so far however.
  • No mechanism to change mti class table name but that is minor
  • More complex testing needed to ensure reliability
  • Uses ARel so should be compatible with ARel supported database that support view; only tested with MySQL
  • SchemaDumper support for omitting views with databases other than MySQL is untested

Create MTI classes by renaming your base table with the core suffix and wrapping your associations in a mti_class block

Test example from http://techspry.com/ruby_and_rails/multiple-table-inheritance-in-rails-3/ which uses mixins to accomplish MTI:

  ActiveRecord::Migration.create_table :restaurants_core, :force => true do |t|
    t.boolean :kids_area
    t.boolean :wifi
    t.integer :food_genre
    t.datetime :created_at
    t.datetime :updated_at
    t.datetime :deleted_at
  end

  ActiveRecord::Migration.create_table :bars_core, :force => true do |t|
    t.string :music_genre
    t.string :best_nights
    t.string :dress_code
    t.datetime :created_at
    t.datetime :updated_at
    t.datetime :deleted_at
  end

  ActiveRecord::Migration.create_table :businesses, :force => true do |t|
    t.integer :biz_id
    t.string :biz_type
    t.string :name
    t.string :address
    t.string :phone
  end

  class Business < ActiveRecord::Base
    belongs_to  :biz, :polymorphic => true
  end

  class Restaurant < ActiveRecord::Base
    mti_class do
      has_one :business, :as => :biz
    end
  end

  class Bar < ActiveRecord::Base
    mti_class(:bars_core) do
      has_one :business, :as => :biz
    end
  end

For now the convention is to name the base tables with the suffix core as the view will use the rails table name

In the background the following association options are used :autosave => true, :validate => true, :dependent => :destroy

MTI associations take the only and except options to limit the inherited columns.

  class SmallMechanic < ActiveRecord::Base
    mti_class :mechanics_core do |t|
      has_one :garage, :foreign_key => :mechanic_id, :except => 'specialty'
    end
  end

  class TinyMechanic < ActiveRecord::Base
    mti_class :mechanics_core do |t|
      has_one :garage, :foreign_key => :mechanic_id, :only => 'specialty'
    end
  end

Validations are also inherited but only for validations for attributes/columns that are inherited

Changing or adding these options will have no effect but the MTI would be senseless without them

If the class does not descend active record the correct table will be used.

If you dont want to use the core suffix convention a table can be specified (see Bar class mti implementation)

  1.9.3p0 :005 > Bar
  => Bar(id: integer, music_genre: string, best_nights: string, dress_code: string, created_at: datetime, updated_at: datetime, deleted_at: datetime, name: string, address: string, phone: string)

  1.9.3p0 :006 > bar = Bar.create(:music_genre => "Latin", :best_nights => "Tuesdays", :dress_code => "casual", :address => "1904 Easy Kaley Orlando, FL 32806", :name => 'Chicos', :phone => '123456789')
  => #<Bar id: 2, music_genre: "Latin", best_nights: "Tuesdays", dress_code: "casual", created_at: "2012-03-09 18:41:17", updated_at: "2012-03-09 18:41:17", deleted_at: nil, name: "Chicos", address: "1904 Easy Kaley Orlando, FL 32806", phone: "123456789">

  1.9.3p0 :008 > bar.phone = '987654321'
   => "987654321" 
  1.9.3p0 :009 > bar.save
   => true

  1.9.3p0 :010 > bar.reload
   => #<Bar id: 2, music_genre: "Latin", best_nights: "Tuesdays", dress_code: "casual", created_at: "2012-03-09 18:41:17", updated_at: "2012-03-09 18:41:17", deleted_at: nil, name: "Chicos", address: "1904 Easy Kaley Orlando, FL 32806", phone: "987654321">

   1.9.3p0 :011 > bar.destroy
    => #<Bar id: 2, music_genre: "Latin", best_nights: "Tuesdays", dress_code: "casual", created_at: "2012-03-09 18:41:17", updated_at: "2012-03-09 18:41:17", deleted_at: nil, name: "Chicos", address: "1904 Easy Kaley Orlando, FL 32806", phone: "987654321">

   1.9.3p0 :013 > Bar.find_by_id(2)
    => nil