views:

676

answers:

4

So I'm just curious about this:

DataMapper uses a mixin for its Models

class Post
  include DataMapper::Resource

While active-record uses inheritance

class Post < ActiveRecord::Base

Does anyone know why DataMapper chose to do it that way (or why AR chose not to)?

+2  A: 

I think the idea is that ActiveRecord considers the database backed aspect to be the key feature of a model class so it inherits that behavior. DataMapper looks like it considers being database backed to just be an aspect of a class that can be added to a class.

That's my guess. Yehuda Katz could tell you definitively.

Ben Hughes
I thought it might be a purely 'philosphical' reason -- Let's see what other people say.
cloudhead
+4  A: 

It lets you inherit from another class that isn't a DM class.

It also allows adding the DM features to a class on the fly. Here's a class method from a module I'm working on right now:

def datamapper_class
  klass = self.dup
  klass.send(:include, DataMapper::Resource)
  klass.storage_names[:default] = @table_name
  klass.property(:id, DataMapper::Types::Serial)
  klass.property(:created_at, DateTime, :nullable => false)
  klass.property(:updated_at, DateTime, :nullable => false)
  columns_with_types { |n, t| klass.property(n, t, :field => n.to_s) }
  klass
end

This lets me take a SAXMachine class (very lightweight) and turn it into a Datamapper class on the fly, and do DataMappery stuff with it. You could even to it to an object's singleton class.

I like to imagine that this lowers my memory footprint when I'm importing 100K objects from XML (I don't use DM for the mass imports), and only mix in the more complex database functions when I need them

Michael Sofaer
interesting, I hadn't thought of that.
cloudhead
+1  A: 

This is really the question of choosing Inheritance v.s. Composition.

I personally favor composition as it appears to be a more natural way of constructing classes and objects.

Composition gives you more control over what behaviors you want to include in your class. As for inheritance you get either everything or nothing. Composition allows you to cherry pick the behaviors you want.

Aaron Qian
+2  A: 

The DataMapper pattern is intended to provide a layer that allows the domain object model to diverge from the schema. ActiveRecord unifies the object model and the relational database structure.

per Martin Fowler:

Objects and relational databases have different mechanisms for structuring data. Many parts of an object, such as collections and inheritance, aren't present in relational databases. When you build an object model with a lot of business logic it's valuable to use these mechanisms to better organize the data and the behavior that goes with it. Doing so leads to variant schemas; that is, the object schema and the relational schema don't match up.

You still need to transfer data between the two schemas, and this data transfer becomes a complexity in its own right. If the in-memory objects know about the relational database structure, changes in one tend to ripple to the other.

The Data Mapper is a layer of software that separates the in-memory objects from the database. Its responsibility is to transfer data between the two and also to isolate them from each other. With Data Mapper the in-memory objects needn't know even that there's a database present; they need no SQL interface code, and certainly no knowledge of the database schema. (The database schema is always ignorant of the objects that use it.) Since it's a form of Mapper (473), Data Mapper itself is even unknown to the domain layer.

MattMcKnight