[~/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>]