Please implement eager loading of nested associations
See http://guides.rubyonrails.org/active_record_querying.html#eager-loading-multiple-associations for how Rails does it.
In the code below, Variant.find can include Product, but what I'd like to be able to do is also include Brand through Product, Category through Product, and Partner through Brand and Product. In the meantime, I'm using the excellent sequelize.query to achieve the raw query I'm looking for.
var Sequelize = require("sequelize") , config = require(__dirname + "/config/config.js") , sequelize = new Sequelize(config.database, config.username, config.password, { dialect: config.dialect, host: config.host, port: config.port, omitNull: true}) var Partner = sequelize.import(__dirname + "/models/partner.js") , Category = sequelize.import(__dirname + "/models/category.js") , Brand = sequelize.import(__dirname + "/models/brand.js") , Product = sequelize.import(__dirname + "/models/product.js") , Variant = sequelize.import(__dirname + "/models/variant.js") Partner.hasMany(Brand) Brand.belongsTo(Partner) Brand.hasMany(Product) Product.belongsTo(Brand) Category.hasMany(Product) Product.belongsTo(Category) Product.hasMany(Variant) Variant.belongsTo(Product) var rawSql = 'SELECT "Variants".*, "Products"."parentSku", "Products"."title", "Products"."description", \ "Products"."CategoryId", "Categories"."name" as "categoryCode", "Categories"."description" AS "Category", \ "Products"."BrandId", "Brands"."description" AS "Brand", "Brands"."PartnerId", "Partners"."name" FROM \ "Variants" LEFT JOIN "Products" ON ("Variants"."ProductId" = "Products"."id") LEFT JOIN "Categories" ON \ ("Products"."CategoryId" = "Categories"."id") LEFT JOIN "Brands" ON ("Products"."BrandId" = "Brands"."id") \ LEFT JOIN "Partners" ON ("Brands"."PartnerId" = "Brands"."PartnerId") WHERE "Variants"."childSku" = ?' var sql = Sequelize.Utils.format([rawSql, "puma-1234-red-large"]) sequelize.sync({ force: true }).success(function() { Partner.create({ name: 'saks' }).success(function(partner) { Brand.create({ name: 'Puma', description: 'Puma Sportswear', PartnerId: partner.id }).success(function(brand) { Category.create({ name: "mn-shirt", description: "Men's shirt" }).success(function(category) { Product.create({ title: "Cool t-shirt", description: "<div>Really handsome t-shirt</div>", parentSku: "puma-1234", CategoryId: category.id, BrandId: brand.id}).success(function(product) { Variant.create({ color: "Red", size: "Large", listPriceCents: "9999", salePriceCents: "4999", childSku: "puma-1234-red-large", ProductId: product.id }).success(function(variant) { Variant.find({ where: ['"Variants"."childSku" = ?', 'puma-1234-red-large'], include: ['Product']}).success(function(lookedUp) { console.log(JSON.stringify({'color' : lookedUp.color, 'parentSku' : lookedUp.product.parentSku, 'childSku' : lookedUp.childSku, 'BrandId' : lookedUp.product.BrandId, 'CategoryId' : lookedUp.product.CategoryId})) sequelize.query(sql).success(function(data){console.log(JSON.stringify(data))}) }) }) }) }) }) }) })
Here's the output
Executing: DROP TABLE IF EXISTS "Partners"; Executing: DROP TABLE IF EXISTS "Categories"; Executing: DROP TABLE IF EXISTS "Brands"; Executing: DROP TABLE IF EXISTS "Products"; Executing: DROP TABLE IF EXISTS "Variants"; Executing: CREATE TABLE IF NOT EXISTS "Partners" ("name" VARCHAR(255) NOT NULL UNIQUE, "id" SERIAL , "createdAt" TIMESTAMP NOT NULL, "updatedAt" TIMESTAMP NOT NULL, PRIMARY KEY ("id")); Executing: CREATE TABLE IF NOT EXISTS "Categories" ("name" VARCHAR(255) NOT NULL UNIQUE, "description" TEXT NOT NULL, "id" SERIAL , "createdAt" TIMESTAMP NOT NULL, "updatedAt" TIMESTAMP NOT NULL, PRIMARY KEY ("id")); Executing: CREATE TABLE IF NOT EXISTS "Brands" ("name" VARCHAR(255) NOT NULL UNIQUE, "description" TEXT NOT NULL, "id" SERIAL , "createdAt" TIMESTAMP NOT NULL, "updatedAt" TIMESTAMP NOT NULL, "PartnerId" INTEGER, PRIMARY KEY ("id")); Executing: CREATE TABLE IF NOT EXISTS "Products" ("title" VARCHAR(255) NOT NULL, "description" TEXT, "parentSku" VARCHAR(255) NOT NULL UNIQUE, "id" SERIAL , "createdAt" TIMESTAMP NOT NULL, "updatedAt" TIMESTAMP NOT NULL, "BrandId" INTEGER, "CategoryId" INTEGER, PRIMARY KEY ("id")); Executing: CREATE TABLE IF NOT EXISTS "Variants" ("color" VARCHAR(255), "size" VARCHAR(255), "listPriceCents" INTEGER NOT NULL, "salePriceCents" INTEGER NOT NULL, "childSku" VARCHAR(255) NOT NULL UNIQUE, "id" SERIAL , "createdAt" TIMESTAMP NOT NULL, "updatedAt" TIMESTAMP NOT NULL, "ProductId" INTEGER, PRIMARY KEY ("id")); Executing: INSERT INTO "Partners" ("name","createdAt","updatedAt") VALUES ('saks','2012-12-29 7:52:15.262000','2012-12-29 7:52:15.262000') RETURNING *; Executing: INSERT INTO "Brands" ("name","description","createdAt","updatedAt","PartnerId") VALUES ('Puma','Puma Sportswear','2012-12-29 7:52:15.266000','2012-12-29 7:52:15.266000',1) RETURNING *; Executing: INSERT INTO "Categories" ("name","description","createdAt","updatedAt") VALUES ('mn-shirt','Men''s shirt','2012-12-29 7:52:15.270000','2012-12-29 7:52:15.270000') RETURNING *; Executing: INSERT INTO "Products" ("title","description","parentSku","createdAt","updatedAt","BrandId","CategoryId") VALUES ('Cool t-shirt','<div>Really handsome t-shirt</div>','puma-1234','2012-12-29 7:52:15.275000','2012-12-29 7:52:15.275000',1,1) RETURNING *; Executing: INSERT INTO "Variants" ("color","size","listPriceCents","salePriceCents","childSku","createdAt","updatedAt","ProductId") VALUES ('Red','Large','9999','4999','puma-1234-red-large','2012-12-29 7:52:15.277000','2012-12-29 7:52:15.278000',1) RETURNING *; Executing: SELECT "Variants".*, "Products"."title" AS "Products.title", "Products"."description" AS "Products.description", "Products"."parentSku" AS "Products.parentSku", "Products"."id" AS "Products.id", "Products"."createdAt" AS "Products.createdAt", "Products"."updatedAt" AS "Products.updatedAt", "Products"."BrandId" AS "Products.BrandId", "Products"."CategoryId" AS "Products.CategoryId" FROM "Variants" LEFT OUTER JOIN "Products" ON "Variants"."ProductId"="Products"."id" WHERE "Variants"."childSku" = 'puma-1234-red-large'; {"color":"Red","parentSku":"puma-1234","childSku":"puma-1234-red-large","BrandId":1,"CategoryId":1} Executing: SELECT "Variants".*, "Products"."parentSku", "Products"."title", "Products"."description", "Products"."CategoryId", "Categories"."name" as "categoryCode", "Categories"."description" AS "Category", "Products"."BrandId", "Brands"."description" AS "Brand", "Brands"."PartnerId", "Partners"."name" FROM "Variants" LEFT JOIN "Products" ON ("Variants"."ProductId" = "Products"."id") LEFT JOIN "Categories" ON ("Products"."CategoryId" = "Categories"."id") LEFT JOIN "Brands" ON ("Products"."BrandId" = "Brands"."id") LEFT JOIN "Partners" ON ("Brands"."PartnerId" = "Brands"."PartnerId") WHERE "Variants"."childSku" = 'puma-1234-red-large' [{"color":"Red","size":"Large","listPriceCents":9999,"salePriceCents":4999,"childSku":"puma-1234-red-large","id":1,"createdAt":"2012-12-29T13:52:15.277Z","updatedAt":"2012-12-29T13:52:15.278Z","ProductId":1,"parentSku":"puma-1234","title":"Cool t-shirt","description":"<div>Really handsome t-shirt</div>","CategoryId":1,"categoryCode":"mn-shirt","Category":"Men's shirt","BrandId":1,"Brand":"Puma Sportswear","PartnerId":1,"name":"saks"}]