Asociaciones Through

[~/rubytesting/database/datamapper/through]$ cat app.rb
require 'data_mapper'

DataMapper::Logger.new($stdout, :debug)
DataMapper.setup(:default, "sqlite3://#{Dir.pwd}/example.db")

class Photo
  include DataMapper::Resource

  property :id, Serial

  has n, :taggings
  has n, :tags, :through => :taggings
end

class Tag
  include DataMapper::Resource

  property :id, Serial

  has n, :taggings
  has n, :photos, :through => :taggings
end

class Tagging
  include DataMapper::Resource

  belongs_to :tag,   :key => true
  belongs_to :photo, :key => true
end

DataMapper.finalize

require  'dm-migrations'

DataMapper.auto_migrate!
#DataMapper.auto_upgrade!

[1] pry(main)> load 'app.rb'
NameError: uninitialized constant Photo::DataMapper
from app.rb:2:in `<class:Photo>'
[2] pry(main)> load 'app.rb'
 ~ (0.003772) PRAGMA table_info("photos")
 ~ (0.000014) PRAGMA table_info("tags")
 ~ (0.000008) PRAGMA table_info("taggings")
 ~ (0.000027) SELECT sqlite_version(*)
 ~ (0.000073) DROP TABLE IF EXISTS "photos"
 ~ (0.000009) PRAGMA table_info("photos")
 ~ (0.001200) CREATE TABLE "photos" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)
 ~ (0.000126) DROP TABLE IF EXISTS "tags"
 ~ (0.000025) PRAGMA table_info("tags")
 ~ (0.000993) CREATE TABLE "tags" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT)
 ~ (0.000101) DROP TABLE IF EXISTS "taggings"
 ~ (0.000015) PRAGMA table_info("taggings")
 ~ (0.001372) CREATE TABLE "taggings" ("tag_id" INTEGER NOT NULL, "photo_id" INTEGER NOT NULL, PRIMARY KEY("tag_id", "photo_id"))
 ~ (0.000965) CREATE INDEX "index_taggings_tag" ON "taggings" ("tag_id")
 ~ (0.001084) CREATE INDEX "index_taggings_photo" ON "taggings" ("photo_id")
=> true

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 "photos" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);
CREATE TABLE "taggings" ("tag_id" INTEGER NOT NULL, "photo_id" INTEGER NOT NULL, PRIMARY KEY("tag_id", "photo_id"));
CREATE TABLE "tags" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT);
CREATE INDEX "index_taggings_photo" ON "taggings" ("photo_id");
CREATE INDEX "index_taggings_tag" ON "taggings" ("tag_id");

[2] pry(main)> ph = Photo.create
 ~ (0.002460) INSERT INTO "photos" DEFAULT VALUES
=> #<Photo @id=1>
[4] pry(main)> tg = Tag.create()
 ~ (0.002559) INSERT INTO "tags" DEFAULT VALUES
=> #<Tag @id=1>
[5] pry(main)> g = Tagging.create(:photo => ph, :tag => tg)
 ~ (0.002547) INSERT INTO "taggings" ("tag_id", "photo_id") VALUES (1, 1)
=> #<Tagging @tag_id=1 @photo_id=1>
[7] pry(main)> ph.tags
 ~ (0.000100) SELECT "tags"."id" FROM "tags" INNER JOIN "taggings" ON "tags"."id" = "taggings"."tag_id" INNER JOIN "photos" ON "taggings"."photo_id" = "photos"."id" WHERE "taggings"."photo_id" = 1 GROUP BY "tags"."id" ORDER BY "tags"."id"
=> [#<Tag @id=1>]
[8] pry(main)> tg.photos
 ~ (0.000080) SELECT "photos"."id" FROM "photos" INNER JOIN "taggings" ON "photos"."id" = "taggings"."photo_id" INNER JOIN "tags" ON "taggings"."tag_id" = "tags"."id" WHERE "taggings"."tag_id" = 1 GROUP BY "photos"."id" ORDER BY "photos"."id"
=> [#<Photo @id=1>]
9] pry(main)> tg2 = Tag.create(:photos => [ph]) 
 ~ (0.005787) INSERT INTO "tags" DEFAULT VALUES
 ~ (0.000534) SELECT "tag_id", "photo_id" FROM "taggings" WHERE ("photo_id" = 1 AND "tag_id" = 1) ORDER BY "tag_id", "photo_id" LIMIT 1
 ~ (0.000049) SELECT "tag_id", "photo_id" FROM "taggings" WHERE ("tag_id" = 2 AND "photo_id" = 1) ORDER BY "tag_id", "photo_id" LIMIT 1
 ~ (0.001444) INSERT INTO "taggings" ("tag_id", "photo_id") VALUES (2, 1)
=> #<Tag @id=2>
[10] pry(main)> ph2 = Photo.create(:tags => [tg, tg2])
 ~ (0.001175) INSERT INTO "photos" DEFAULT VALUES
 ~ (0.000056) SELECT "tag_id", "photo_id" FROM "taggings" WHERE ("tag_id" = 1 AND "photo_id" = 1) ORDER BY "tag_id", "photo_id" LIMIT 1
 ~ (0.000045) SELECT "tag_id", "photo_id" FROM "taggings" WHERE ("photo_id" = 2 AND "tag_id" = 1) ORDER BY "tag_id", "photo_id" LIMIT 1
 ~ (0.001047) INSERT INTO "taggings" ("tag_id", "photo_id") VALUES (1, 2)
 ~ (0.000079) SELECT "tag_id", "photo_id" FROM "taggings" WHERE ("photo_id" = 2 AND "tag_id" = 2) ORDER BY "tag_id", "photo_id" LIMIT 1
 ~ (0.001070) INSERT INTO "taggings" ("tag_id", "photo_id") VALUES (2, 2)
=> #<Photo @id=2>
[11] pry(main)> ph2.tags
=> [#<Tag @id=1>, #<Tag @id=2>]



Casiano Rodriguez León 2015-01-07