Peter Bengtson
unread,Oct 31, 2009, 8:53:15 AM10/31/09Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to CouchRest
I need to implement a Ruby persistence layer on top of CouchDB. The
infrastructure provided by CouchRest seems to be excellent. My
application, however, has some special, though not very unusual,
requirements. Thus I'd like to pick the brains of the CouchRest
community as to the feasibility of extending CouchRest. Maybe what I'm
looking for has already been implemented elsewhere, who knows.
It needs to support class inheritance, and it must be possible to pull
an object from the DB without knowing its class in advance. The views
must also support mapping over instances belonging to subclasses.
The following idiom is very natural to anyone coming from
ActiveRecord:
foo = Foo.get(some_id)
However, CouchRest already stores the class of the document as the
value of the property "couchrest-class". This means that the above
Ruby statement contains one rather substantial redundancy: "Foo.get"
will construct a Foo object and nothing else. (However, CouchRest
doesn't check that the "couchrest-class" property matches the class
explicitly given in the object itself: in fact, it is quite possible
to construct a Bar instance instead without anything untoward
happening.)
What I need is a way of pulling an object from CouchDB which invokes
the constructor of the class given by the "couchrest-class" object,
rather like the following:
foo = ExtendedDocument.get(some_id)
However, this always returns an ExtendedDocument instance because
CouchRest::Mixins::DocumentQueries.get uses "new" (on line 58 of
document_queries.rb) to construct the in-memory instance.
If instead of new, line 58 read:
doc['couchrest-class'].constantize.send(:new, doc)
Then this would always return an object of the class specified by the
object *itself*, rather than of an explicitly supplied class directly
stated in the loading code as in ActiveRecord.
Would this be a change compatible with the current code base, or would
it be better to add a new class, such as "General" to do this?
I'm also wondering whether views could be easily modified to take
subclasses into account during mapping operations. For instance,
something like the following:
class Human < SomeBasicCouchDBClass; end
class Woman < Human; end
class Man < Human; end
Assume we create 3 Women and 2 Men, but no Humans. As the code stands
today, evaluating "Human.all.length" returns 0, since the view code
checks for an exact class match. If would be fairly easy to add a new
method to check for subclass matches, e.g. "all_deep" or similar which
would invoke a new view created for the purpose.
Any thoughts on best CouchRest practices?