CachedModels 0.0.3

Posted by luca
on Wednesday, October 22

Since I began to work as professional developer I learned a lot of stuff, but, first of all I learned to be honest with customers and with the Community.
I have to admit: CachedModels 0.0.2 was a huge mess.

It was a broken version, due to wrong mocks in test. I apologize for all the problems you could encountered using it. Since I discovered all the errors, I worked hard to restore all the lost functionalities.
But it wasn't enough for me, so I focused my attention on performances, reducing cache accesses: now benchmark test tooks 36.015132 fewer seconds than plain ActiveRecord!

I hope you would appreciate my honesty and newest version of my plugin. Enjoy!

CachedModels 0.0.2

Posted by luca
on Friday, October 10

CachedModels hit 0.0.2.

First of all, I transformed it to a Ruby gem, so you can use it outside Rails! Second, I dramatically enhanced performances, avoiding useless cache lookups and expirations. Take a look at the new benchmark stats: 1000 requests with a level of concurrency equal to 100, tooks 6 fewer seconds, if compared with standard ActiveRecord.

I strongly encourage you to upgrade to the newer version.

Cached Models 1

Posted by luca
on Wednesday, September 10

cached_models provides to your models a transparent approach to use Rails internal cache mechanism.

Usually, when you decide to use cache for your ActiveRecord results, you have to manually implement complex expiring policies.
cached_models simplifies your code:

class Author < ActiveRecord::Base
  has_many :posts, :cached => true
end

class Post < ActiveRecord::Base
  belongs_to :author, :cached => true
end

That's all!!.

A more complex example..

class Project < ActiveRecord::Base
  has_many :developers, :cached => true

  has_many :tickets, :cached => true
  has_many :recent_tickets, :limit => 5,
    :order => 'id DESC', :cached => true
end

class Developer < ActiveRecord::Base
  belongs_to :project, :cached => true
end

Example 1

project.developers # Database fetch and automatic cache storing

developer = project.developers.last
developer.update_attributes :first_name => 'Luca' # Database update and cache expiration for project cache

Example 2

# Fetch associated collection for both the projects
project.developers
project2.developers

developer = project.developers.last
project2.developers << developer # Database update and cache renewal for both project and project2 caches

Example 3

project.tickets # Database fetch and automatic cache storing
ticket = project.recent_tickets.first
ticket.update_attributes :state => 'solved' # Database update and cache expiration for both tickets and recent_tickets entries

The current version works only with the has_many macro.

How to install

$ ./script/plugin install git://github.com/jodosha/cached_models.git

Official page

http://lucaguidi.com/pages/cached_models

Cached Models

Posted by luca
on Wednesday, September 10

CachedModels provides to your models a transparent approach to use ActiveSupport cache mechanism.

Usually, when you decide to use cache for your ActiveRecord results, you have to manually implement complex expiring policies, like the following:

class Author < ActiveRecord::Base
  has_many :posts

  after_save :expire_cache

  def cached_posts
    Rails.cache.fetch("#{cache_key}/posts") { self.posts }
  end

  private
    def expire_cache
      Rails.cache.delete("#{cache_key}/posts")
    end
end

class Post < ActiveRecord::Base
  belongs_to :author

  after_save :expire_cache

  private
    def expire_cache
      Rails.cache.delete("#{author.cache_key}/posts")
    end
end

The problem with this kind of approach is that the code complexity grows on the cached-stuff growing. If I would to add has_many :recent_posts and cache the results, I should write other bureaucracy code, for observing my objects.
Note that the above code is incomplete, because doesn't handles a lot of cased provided by the has_many macro. For instance:
post = author.posts.last
another_author.posts << post

The second instruction should expire caches for both the models, cache values are now inconsistent. This means, of course, write other code and add code complexity.

Solution

It would be nice to DRYup your caching code. Here the cached_models approach:

class Author < ActiveRecord::Base
  has_many :posts, :cached => true
end

class Post < ActiveRecord::Base
  belongs_to :author, :cached => true
end

That's all!!.

A more complex example..

class Project < ActiveRecord::Base
  has_many :developers, :cached => true

  has_many :tickets, :cached => true
  has_many :recent_tickets, :limit => 5,
    :order => 'id DESC', :cached => true
end

class Developer < ActiveRecord::Base
  belongs_to :project, :cached => true
end

Example 1

project.developers # Database fetch and automatic cache storing

developer = project.developers.last
developer.update_attributes :first_name => 'Luca' # Database update and cache expiration for project cache

Example 2

# Fetch associated collection for both the projects
project.developers
project2.developers

developer = project.developers.last
project2.developers << developer # Database update and cache renewal for both project and project2 caches

Example 3

project.tickets # Database fetch and automatic cache storing
ticket = project.recent_tickets.first
ticket.update_attributes :state => 'solved' # Database update and cache expiration for both tickets and recent_tickets entries

Installation

There are three ways to install CachedModels:

Gemified Rails plugin

#config/environment.rb
Rails::Initializer.run do |config|
  config.gem 'cached-models'
end
$ (sudo) rake gems:install
$ rake gems:unpack

Rails plugin

$ ./script/plugin install git://github.com/jodosha/cached-models.git

Standalone

$ (sudo) gem install cached-models
require 'rubygems'
require 'activerecord'
require 'cached-models'

ActiveRecord::Base.rails_cache = ActiveSupport::Cache.lookup_store(:mem_cache_store, 'localhost')

Issues

The current version works only with the has_many macro.

Make sure to configure your current environment with:

config.cache_classes = true
config.action_controller.perform_caching = true
config.cache_store = :mem_cache_store

Repository

http://github.com/jodosha/cached-models/tree/master

How to contribute

      Check out the code and test it:
      $ ./script/plugin install git://github.com/jodosha/cached-models.git
      Create a ticket to the Sushistar Lighthouse page
      Create a patch and add as attachment to the ticket.