solnic/dm-mapper — Issue #1: Database API suggestion
Author: jgaskins
Created: 2012-02-13 07:35:47+00:00
State: open

## Methods on Mapper itself

These are the methods I've been thinking about while screwing around with [my own implementation](https://github.com/jgaskins/perpetuity):

`Mapper.all`: Using "find" with no arguments (as suggested in the Readme) seems weird. "Find" is a transitive verb, so you'd expect to be "finding" something specific.

`Mapper.retrieve(query)`: Retrieve objects from the DB. `query` could be a hash with the following options:

* Equality: Simple, ActiveRecord-style query hashes like those already implemented
* Inequality: `Article::Mapper.retrieve(views: { greater_than: 100 })`
* Inclusion: `Article::Mapper.retrieve(tags: { includes: %w(ruby rails) })`
* Range: `Article::Mapper.retrieve(published_at: (1.month.ago..Time.now)`

`Mapper.find(id)`: Retrieve the object with the specified ID. Arguably, `find` and `retrieve` could be swapped, depending on the connotations of each.

`Mapper.insert(object)`: Insert the specified object into the DB. Raise an exception if object.class != mapped_class because someone's sure to call `Article::Mapper.insert(user)`.

`Mapper.update(object)`: Update the object in the DB. Saves any changes to the object since last persisted.

`Mapper.update_with_attributes(object, attributes)`: Similar to `#update`, but you pass an attributes hash with the changes. Good for a Rails controller update action to keep it short.

`Mapper.delete(object)`: Delete that bad boy.

## Daisy-chaining of methods

ActiveRecord's method chaining functionality is pretty nice. Being able to say `Article::Mapper.retrieve(published: true)` could return an object (say, DataMapper::Retrieval) that includes Enumerable so that we could call methods like `articles.sort(:published_at).reverse` on them.

I'd prefer to keep the API for the retrieved records as close to Ruby's Array methods as possible. I don't like the ARel style where you just end up writing Rubified SQL (`articles.order(:published_at, :desc)`). I don't like SQL. I do like Ruby. ;-)