DataMapper - Introdução

#dev, #ruby

Ultimamente tenho passado a usar cada vez menos MongoDb e voltado a usar banco de dados SQL.

Para usar SQL gosto do ActiveRecord ou o DataMapper. Já falei de ActiveRecord em posts como ActiveRecord sem Rails e hoje veremos um exemplo similar usando DataMapper.

Como de costume um Gemfile:

source "http://rubygems.org"

gem "data_mapper"
gem "dm-sqlite-adapter"

Vamos criar nosso model de mensagem no arquivo message.rb:

class Message
  include DataMapper::Resource

  property :id, Serial
  property :content, String
  property :created_at, DateTime
end

Para se conectar ao banco de dados é necessário usar o DataMapper#setup:

DataMapper.setup(:default, "sqlite://#{File.expand_path('database.db')}")

Nesse caso vou usar um banco de dados sqlite, mas se for usar um PostgreSQL:

DataMapper.setup(:default, 'postgres://user:password@hostname/database')

Ao contrário do ActiveRecord não precisamos criar um arquivo de migration. Depois de fazer o require do model message.rb temos duas formas de levantar o banco de dados: DataMapper.auto_migrate! e o DataMapper.auto_upgrade!.

O DataMapper.auto_migrate! tem a característica de APAGAR as tabelas antes de tentar criá-las, já o DataMapper.auto_upgrade! apenas vai tentar fazer com que o schema “case” com o(s) model(s).

Vou criar agora um arquivo chamado database.rb que terá a função de “levantar” e migrar o banco de dados:

require "data_mapper"

DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, "sqlite://#{File.expand_path('database.db')}")

Dir["./models/*.rb"].entries.each do |model|
  require model
end

DataMapper.auto_upgrade!

Usando o irb como “console” podemos testar:

$ irb -r ./database.rb
 ~ (0.000308) PRAGMA table_info("messages")
 ~ (0.000026) SELECT sqlite_version(*)
 ~ (0.109057) CREATE TABLE "messages" ("id" INTEGER NOT NULL PRIMARY KEY AU
TOINCREMENT, "content" VARCHAR(50), "created_at" TIMESTAMP)
irb(main):001:0> Message.count
 ~ (0.000055) SELECT COUNT(*) FROM "messages"
=> 0
irb(main):002:0> Message.create(:content => "Hello from DataMapper")
 ~ (0.111596) INSERT INTO "messages" ("content", "created_at") VALUES ('Hel
lo from DataMapper', '2013-07-31T07:39:21-03:00')
=> #<Message @id=1 @content="Hello from DataMapper" @created_at=#<DateTime:
 2013-07-31T07:39:21-03:00 ((2456505j,38361s,436990591n),-10800s,2299161j)>
>
irb(main):003:0> Message.first
 ~ (0.000085) SELECT "id", "content", "created_at" FROM "messages" ORDER BY
 "id" LIMIT 1
=> #<Message @id=1 @content="Hello from DataMapper" @created_at=#<DateTime:
 2013-07-31T07:39:21-03:00 ((2456505j,38361s,0n),-10800s,2299161j)>>

O código está disponível no github em: https://github.com/dmitrynix/data-mapper-intro.