4. DataMapper 0.10 is Released
DataMapper 0.10 is ready for release. We’ve worked on it
for the past 11 months, pushed 1250 commits, written
3000+ specs, and fixed 140 tickets in the process.
5. 1.8
1.9
JRuby
Windows *
* Sorry, no Windows / 1.9 yet...
20. 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))
Eager loading
24. 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
27. Person.all(Person.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"
Complex querying!
28. class Person
include DataMapper::Resource
property :id, Serial
property :name, String
property :age, Integer
has n, :addresses
def self.named_like_me
all(:name.like => "%me%")
end
def self.older_than_me
all(:age.gt => 27)
end
end
Person.named_like_me.older_than_me
~ SELECT "id", "name", "age" FROM "people"
WHERE ("name" LIKE '%me%' AND "age" > 27) ORDER BY "id"
Query chaining
29. class Person
s
include DataMapper::Resource
e
property :id, Serial
p
property :name, String
o y
property :age, Integer
c b
s u
has n, :addresses
d R
def self.named_like_me
e
all(:name.like => "%me%")
end
m in
a la
def self.older_than_me
all(:age.gt => 27)
N p
end
end
i n
Person.named_like_me.older_than_me
~ SELECT "id", "name", "age" FROM "people"
WHERE ("name" LIKE '%me%' AND "age" > 27) ORDER BY "id"
Query chaining
30. 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"
Subqueries
35. class Person
...
property :name, String, :nullable => false
end
CREATE TABLE "people" ("id" SERIAL NOT NULL,
"name" VARCHAR(50) NOT NULL,
"age" INTEGER, PRIMARY KEY("id"))
Automatic Validations
36. Person.create
DataObjects::IntegrityError: ERROR:
null value in column "name" violates not-null constraint
37. person = Person.create
p person.errors => #<DataMapper::Validate::ValidationErrors:0x101d217a0
@errors={:name=>["Name must not be blank"]},
@resource=#<Person @id=nil @name=nil @age=nil>>
38. class Person
...
validates_present :name
end
Validations
39. class Person
...
property :created_at, DateTime
property :updated_at, DateTime
end
Timestamps
41. class Person
...
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
Constraints
42. module DataMapper
module Types
class IPAddress < DataMapper::Type
primitive String
length 16
def self.load(value, property)
IPAddr.new(value)
end
def self.dump(value, property)
value.to_s
end
def self.typecast(value, property)
value.kind_of?(IPAddr) ? value : load(value, property)
end
end
end
end
class NetworkNode
...
property :ipaddress, IPAddress
end
Custom types
43.
44. class Address
include DataMapper::EmbeddedValue
property :street, String
end
class Person
include DataMapper::Resource
property :id, Serial
property :name, String
has n, :addresses
end