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") => trueEste 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) => trueAhora 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