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