public
Description: a way to find out 'what really changed' via datamapper observers
Clone URL: git://github.com/atmos/dm-references.git
name age message
file LICENSE Wed Jul 02 00:06:55 -0700 2008 add license and todo [atmos]
file README Wed Jul 02 13:07:10 -0700 2008 readme update [atmos]
file Rakefile Thu Sep 11 10:23:50 -0700 2008 version bumps to make ci happy again [atmos]
file TODO Wed Jul 02 00:06:55 -0700 2008 add license and todo [atmos]
file dm-references.gemspec Wed Jul 02 13:07:10 -0700 2008 readme update [atmos]
directory lib/ Wed Jul 02 00:02:04 -0700 2008 couple of small fixups [atmos]
directory script/ Tue Jul 01 22:57:43 -0700 2008 initial import [atmos]
directory spec/ Thu Sep 11 10:25:58 -0700 2008 use create instead of create! in specs [atmos]
README
dm-references
=============

A dm-plugin gem that lets you build little rules to let you know when objects of importance change.

Right now I'm building a merb app that serves up 8-10MB xml documents.  In a lot of cases
these docs take 60 seconds or so to generate fresh.  We've been memcaching things heavily, 
but figuring out which portions of the document became invalid when data was modified was
really tough, so we'd invalidate the whole document. :(

The other week I noticed the dm-observers gem and I figured I could take advantage of it 
to make our lives easier.  dm-references let's you build a little lookup table of sorts
for all of the datamapper resources that your ruby process knows about.  The lookup table
basically maps a class to one or more blocks that will find the object of importance in 
the object graph.  The modified object will then have an instance variable called
updated_parents, this returns an array of objects that I may or may not want to act on.  In
the case of my web app, I'm using these objects to expire fragments associated with the
changes to the object_of_importance.  This is actually quite cool because it allows me to
build rules into the data model and share things with the presentation layer w/o doing 
hacky shit to make the two talk.

Example
=======

mpro% irb
>> require 'spec/spec_helper'; require 'spec/models/label'; require 'spec/models/artist'
=> true
>> Label.auto_migrate!; Artist.auto_migrate!
=> true
>> @label = Label.create!(:name => '1320 Records')
=> #<Label id=1 name="1320 Records">
>> DataMapper::References::RuleSet.prepare do |rc|
?>   rc.references(Artist) { |artist| artist.label }
>> end
=> [#<Proc:0x012db774@(irb):5>]
>> DataMapper::References::RuleSet.apply
=> true
>> @artist = Artist.create(:name => 'Pnuma Trio', :label_id => @label.id)
=> #<Artist id=1 name="Pnuma Trio" label_id=1>
>> @artist.updated_parents
=> [#<Label id=1 name="1320 Records">]