Dirkjan Bussink
   http://github.com/dbussink
          @dbussink
Why?
Declarative
class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :required => true
  property :age, Integer
end
Automatic
migrations
DataMapper.auto_migrate!

DataMapper.auto_upgrade!
Storage
constraints
class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :required => true
  property :age, Integer
end
class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :required => true
  property :age, Integer
end



CREATE TABLE "people" ("id" SERIAL NOT NULL,
                       "name" VARCHAR(50) NOT NULL,
                       "age" INTEGER, PRIMARY KEY("id"))
class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :required => true
  property :age, Integer

  has n, :addresses, :constraint => :destroy!
end
class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :required => true
  property :age, Integer

  has n, :addresses, :constraint => :destroy!
end

ALTER TABLE addresses
ADD CONSTRAINT addresses_person_id_fk
FOREIGN KEY (person_id)
REFERENCES people ON DELETE CASCADE ON UPDATE CASCADE
Automatic
validations
class Person
  include DataMapper::Resource
  property :id, Serial
  property :name, String, :required => true
  property :age, Integer
end
class Person
      include DataMapper::Resource
      property :id, Serial
      property :name, String, :required => true
      property :age, Integer
    end

person = Person.create
person.errors => #<DataMapper::Validations::ValidationErrors:0x101d217a0
                   @errors={:name=>["Name must not be blank"]},
                   @resource=#<Person @id=nil @name=nil @age=nil>>
http://www.flickr.com/photos/jon_truran
Convenience
"that just pisses me off"
Lazyness
people = Person.all
~ Query log empty...
people = Person.all
     ~ Query log empty...


p people
~ SELECT "id", "name" FROM people
:each
people = Person.all
people.each do |person|
  p person.addresses
end
people = Person.all
people.each do |person|
  p person.addresses
end
SELECT "id", "name" FROM people;
SELECT "id", "street" FROM addresses WHERE ("person_id" IN (1,2,3))
Complex
 queries
Person.all(:addresses => {:street.like => "%street%"})
Person.all(:addresses => {:street.like => "%street%"})



    SELECT   "people"."id", "people"."name", "people"."age" FROM "people"
INNER JOIN   "addresses" ON "people"."id" = "addresses"."person_id"
     WHERE   "addresses"."street" LIKE '%street%'
  GROUP BY   "people"."id", "people"."name", "people"."age"
  ORDER BY   "people"."id"
class Person
  include DataMapper::Resource

  ...

  def self.named_like_me
    all(:name.like => "%me%")
  end

end
class Person
  include DataMapper::Resource

  ...

  def self.named_like_me
    all(:name.like => "%me%")
  end

end

Person.named_like_me.all(:age.gt => 27)

~ SELECT "id", "name", "age" FROM "people"
   WHERE ("name" LIKE '%me%' AND "age" > 27) ORDER BY "id"
Person.all(:name.like => '%me%').addresses.all(:street.not => nil)
Person.all(:name.like => '%me%').addresses.all(:street.not => nil)


  SELECT "id", "street", "person_id" FROM "addresses"
   WHERE (
           "person_id" IN (SELECT "id" FROM "people" WHERE "name" LIKE '%me%')
           AND "street" IS NOT NULL
   ) ORDER BY "id"
Person.all - Person.all(:name => 'Dan Kubb')
Person.all - Person.all(:name => 'Dan Kubb')


      SELECT * FROM people WHERE NOT(name = 'Dan Kubb')
Not SQL centric
DataMapper.setup(:default, "postgres://postgres@localhost/dm")
DataMapper.setup(:docs, "mongo://user@localhost/dm")
class Post
  include DataMapper::Resource
  has n, :audits
end

class Audit
  include DataMapper::Resource
  def self.default_repository_name
    :log
  end
end
Custom
adapters
module DataMapper
  module Adapters

    class MyStorageAdapter < AbstractAdapter

      def create(resources)
      end

      def read(query)
      end

      def update(attributes, collection)
      end

      def delete(collection)
      end

    end
  end
end
Future
class Address
  include DataMapper::EmbeddedValue

  property :street,       String
end

class Person
  include DataMapper::Resource

  property :id,       Serial
  property :name,     String
  has n, :addresses
end
drops into2008
Back to   Rails
      1.0
1.8 / 1.9
(on Windows too)
Dan Kubb

Martin Gamsjaeger
http://datamapper.org/
      http://github.com/datamapper
              @datamapper
http://groups.google.com/group/datamapper
      irc://irc.freenode.net/#datamapper

Datamapper @ Railsconf2010