Post "has many" Comments, or a
Comment belongs to a Post.
The types of associations currently in DataMapper are:
has n has 1 belongs_to has n, :things, :through => Resource has n, :things, :through => :model
Este código se encuentra en: app.rb
[~/rubytesting/database/datamapper/two(master)]$ cat app.rb
require 'data_mapper'
DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/example.db")
class Post
include DataMapper::Resource
property :id, Serial
property :text, Text
has n, :comments
end
class Comment
include DataMapper::Resource
property :id, Serial
property :text, Text
belongs_to :post # defaults to :required => true
end
DataMapper.finalize
require 'dm-migrations'
#DataMapper.auto_migrate!
DataMapper.auto_upgrade!
The belongs_to method accepts a few options.
belongs_to relationships will be required by default
You can make the parent resource optional by passing
:required => false
as an option to belongs_to.
:key => true option.
Arrancamos Pry
[~/rubytesting/database/datamapper/two]$ pryy cargamos
./app.rb
[1] pry(main)> load './app.rb'
~ (0.000397) PRAGMA table_info("posts")
~ (0.000019) SELECT sqlite_version(*)
~ (0.001237) CREATE TABLE "posts" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "text" TEXT)
~ (0.000011) PRAGMA table_info("comments")
~ (0.000986) CREATE TABLE "comments" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "text" TEXT, "post_id" INTEGER NOT NULL)
~ (0.000964) CREATE INDEX "index_comments_post" ON "comments" ("post_id")
=> true
Este es el esquema de la base de datos creada a partir de las clases
Post y Comment:
[~/rubytesting/database/datamapper/two(master)]$ sqlite3 example.db
SQLite version 3.7.11 2012-03-20 11:35:50
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .schema
CREATE TABLE "comments" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"text" TEXT,
"post_id" INTEGER NOT NULL);
CREATE TABLE "posts" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
"text" TEXT);
CREATE INDEX "index_comments_post" ON "comments" ("post_id");
Ahora podemos crear un objeto Post:
[2] pry(main)> pp = Post.create(:text => 'hello world!')
~ (0.000888) INSERT INTO "posts" ("text") VALUES ('hello world!')
=> #<Post @id=1 @text="hello world!">
Sus comments están vacíos:
[3] pry(main)> pp.comments ~ (0.000051) SELECT "id", "post_id" FROM "comments" WHERE "post_id" = 1 ORDER BY "id" => []
Adding resources to a relationship, can be done in different ways.
[2] pry(main)> co = Comment.new(:text => "Nice greeting!")
=> #<Comment @id=nil @text="Nice greeting!" @post_id=nil>
[3] pry(main)> pp = Post.create(:text => 'hello world!')
~ (0.001294) INSERT INTO "posts" ("text") VALUES ('hello world!')
=> #<Post @id=1 @text="hello world!">
[4] pry(main)> co.post=pp
=> #<Post @id=1 @text="hello world!">
[5] pry(main)> co.save
~ (0.002974) INSERT INTO "comments" ("text", "post_id") VALUES ('Nice greeting!', 1)
=> true
[7] pry(main)> pp.comments
~ (0.000074) SELECT "id", "post_id" FROM "comments" WHERE "post_id" = 1 ORDER BY "id"
=> [#<Comment @id=1 @text=<not loaded> @post_id=1>]
[8] pry(main)> pp.comments[0].text
~ (0.000193) SELECT "id", "text" FROM "comments" WHERE "id" = 1 ORDER BY "id"
=> "Nice greeting!"
belongs_to relationships will be required by default
We can make the parent resource optional by passing
:required => false
as an option to belongs_to.
[12] pry(main)> c2 = Comment.create(:text => 'silly comment')
=> #<Comment @id=nil @text="silly comment" @post_id=nil>
[13] pry(main)> c2.save
=> false
[14] pry(main)> c2.post = pp
=> #<Post @id=1 @text="hello world!">
[15] pry(main)> c2.save
~ (0.001910) INSERT INTO "comments" ("text", "post_id") VALUES ('silly comment', 1)
=> true
[6] pry(main)> pp.comments.push(Comment.create(:text => "Nice greeting!")) => [#<Comment @id=nil @text="Nice greeting!" @post_id=1>] [4] pry(main)> pp => #<Post @id=1 @text="hello world!"> [5] pry(main)> pp.comments => [#<Comment @id=nil @text="Nice greeting!" @post_id=1>]Esto no ha guardado
pp en la base de datos. Ha sido modificado en memoria.
Tampoco se ha guardado en la base de datos el objeto comentario.
[7] pry(main)> pp.save
~ (0.002523) INSERT INTO "comments" ("text", "post_id") VALUES ('Nice greeting!', 1)
=> true
Ahora las tablas contienen:
sqlite> select * from posts; 1|hello world! sqlite> select * from comments; 1|Nice greeting!|1
[8] pry(main)> c2 = Comment.create(:text => "Do we know each other?")
=> #<Comment @id=nil @text="Do we know each other?" @post_id=nil>
[9] pry(main)> c2.post= pp
=> #<Post @id=1 @text="hello world!">
[10] pry(main)> c2
=> #<Comment @id=nil @text="Do we know each other?" @post_id=1>
[11] pry(main)> c2.save
~ (0.007430) INSERT INTO "comments" ("text", "post_id") VALUES ('Do we know each other?', 1)
=> true
[12] pry(main)> pp.comments
=> [#<Comment @id=1 @text="Nice greeting!" @post_id=1>]
[16] pry(main)> aa = Post.all
~ (0.000065) SELECT "id" FROM "posts" ORDER BY "id"
=> [#<Post @id=1 @text=<not loaded>>]
[17] pry(main)> aa[0].text
~ (0.000052) SELECT "id", "text" FROM "posts" WHERE "id" = 1 ORDER BY "id"
=> "hello world!"
[20] pry(main)> aa[0].comments
~ (0.000052) SELECT "id", "post_id" FROM "comments" WHERE "post_id" = 1 ORDER BY "id"
=> [#<Comment @id=1 @text=<not loaded> @post_id=1>,
#<Comment @id=2 @text=<not loaded> @post_id=1>]
Casiano Rodriguez León 2015-01-07