Bugs: Browse | Submit New | Admin

[#6822] caching single-inheritance hierarchies

Date:
2006-11-22 10:27
Priority:
3
Submitted By:
Sergey Yanovitsky (jah)
Assigned To:
Eric Hodel (drbrain)
Category:
cached_model
State:
Open
Summary:
caching single-inheritance hierarchies

Detailed description
Here attached is the diff that patches the cached_model to  cache correctly  descendants in single inheritance models.


For example: We have some contacts that might be on might not be a users of our service. We want to represent them as
the following class hierarchy.

class Contact < ActiveRecord:Base
end

class AddressBookEntry < Contact
end

class User < Contact
end

So we have the migration:

class CreateContacts < ActiveRecord::Migration
  def self.up
    create_table :contacts do |t|
      # common attributes
      t.column :name, :string, :null => false
      t.column :insertions, :string
      t.column :surname, :string, :null => false
      t.column :company, :string
      t.column :num_internal, :string
      t.column :num_other, :text
      t.column :address, :string
      t.column :postal, :string
      t.column :city, :string
      t.column :email, :string
      t.column :notes, :text
      t.column :type, :string
      t.column :created_at, :timestamp
      t.column :updated_at, :timestamp

      # attributes for type=User
      t.column :login, :string
      t.column :passwd, :string
      t.column :salt, :string
    end

    execute <<-ALTER
      ALTER TABLE contacts ALTER COLUMN created_at SET DEFAULT now();
      ALTER TABLE contacts ALTER COLUMN updated_at SET DEFAULT now();
    ALTER
  end

  def self.down
    drop_table :contacts
  end
end


This stores all those records in one table for all class objects of given hierarchy. The difference on SQL level between
these objects is the value of 'type' column, but id is unique among all of these stored objects.

So idea is brain-dead simple: we cache these objects tagged with their base class name (Contact in our case) and object's
id which is unique in hierarchy.

Ruby Object.base_class always returns the topmost class in the inheritance ierarchy, so we put it in tag generation
and change the regular expression a little bit in find_by_sql to understand Rail's way of fetching such objects.

In our case Rails will produce SQLs like:
SELECT * FROM contacts WHERE (contacts.id = 1) AND ( (contacts."type" = 'Contact' OR contacts."type"
= 'AddressBookEntry' OR contacts."type" = 'User' ) ) LIMIT 1

Patched cached_model will store this object in cache with tag active_record:Contact:1.

Cheers.

Add A Comment: Notepad

Please login


Followup

No Followups Have Been Posted

Attached Files:

Name Description Download
cached_model.diff the patch itself Download

Changes:

Field Old Value Date By
File Added973: cached_model.diff2006-11-22 10:29jah