2017-01-25 11 views
1

PostgresデータベースでSequelizeを使用する、自分のアプリケーションのDELETEルートを設定しようとしています。私は2つの異なるモデル、 "Product"と "Interest"(Interestを一種のカテゴリまたはタグと考える)を持っています。商品には複数のインタレストがあり、インタレストには複数の商品が含まれる可能性があるので、belongsToManyの関連付けを使用しています。その結果、私は3つのテーブル:Products,Interests、およびProductInterestsを持っています。利益のためにSequelize Model - belongsToManyでアイテムを削除するn:m association

Product.belongsToMany(models.Interest, { 
    foreignKey: 'productId', 
    through: models.ProductInterest, 
    as: 'interests', 
    onDelete: 'CASCADE', 
    hooks: true 
}); 

::製品については

:ここで私が連想設定している方法です

Interest.belongsToMany(models.Product, { 
    through: models.ProductInterest, 
    as: 'products', 
    foreignKey: 'interestId', 
    onDelete: 'CASCADE', 
    hooks: true 
}); 

そして、これは製品のための私のコントローラに呼び出されるメソッドです:

destroy(req, res) { 
    return Product 
     .findById(req.params.productId, { 
      include: [ 
       { 
        association: Product.associations.interests 
       } 
      ] 
     }) 
     .then((product) => { 
      if (!product) { 
       return res.status(404).send({ 
        message: 'Product not found' 
       }); 
      } 
      return product 
       .destroy() 
       // I've also tried the following: 
       // .destroy({ 
       // truncate: true, 
       // cascade: true 
       // }) 
       .then(() => res.status(204).send()) 
       .catch(error => res.status(400).send(error)); 
     }) 
     .catch(error => res.status(400).send(error)); 

これにより、無限ループが発生し、これらのクエリがログに記録されます。

Executing (default): SELECT "Product"."id", "Product"."title", "Product"."brand", "Product"."url", "Product"."imageUrl", "Product"."currentPrice", "Product"."male", "Product"."female", "Product"."asin", "Product"."storeName", "Product"."createdAt", "Product"."updatedAt", "ProductInterest"."createdAt" AS "ProductInterest.createdAt", "ProductInterest"."updatedAt" AS "ProductInterest.updatedAt", "ProductInterest"."interestId" AS "ProductInterest.interestId", "ProductInterest"."productId" AS "ProductInterest.productId" FROM "Products" AS "Product" INNER JOIN "ProductInterests" AS "ProductInterest" ON "Product"."id" = "ProductInterest"."productId" AND "ProductInterest"."interestId" = 1; 
Executing (default): SELECT "Interest"."id", "Interest"."name", "Interest"."createdAt", "Interest"."updatedAt", "ProductInterest"."createdAt" AS "ProductInterest.createdAt", "ProductInterest"."updatedAt" AS "ProductInterest.updatedAt", "ProductInterest"."interestId" AS "ProductInterest.interestId", "ProductInterest"."productId" AS "ProductInterest.productId" FROM "Interests" AS "Interest" INNER JOIN "ProductInterests" AS "ProductInterest" ON "Interest"."id" = "ProductInterest"."interestId" AND "ProductInterest"."productId" = 6; 

私の意図は、a)製品表で製品を削除することです。 b)ProductInterestテーブル内の関連レコードを削除する。私は、製品が削除されている場合には、インタレスト自体を削除したくありません。同様に、インタレストが削除された場合(関連のみ)、関連する商品を削除したくありません。

私はこれを回避していくつかの異なる順列を試しましたが、正しい方法を見つけることができません。どんな助けもありがとう。

UPDATE

ビットは、私がそのようなcascadeを使用すべきではないと思うように私を導いたsequelizeコードをデバッグします。それは基本的に(カスケードのために)興味のある商品(削除したい商品)を削除しようとしています。正しい解決策はです。私の理解から

答えて

0

belongsToManyは、与えられたソースとターゲットのために参加し、テーブルモデルを作成する - ので、あなたの二つのテーブルProductInterestため、 はProduct.belongsToMany(Interest)を行うことは、本質的のProductId/InterestIdのちょうどテーブルで新しいテーブルProductInterestを作成し、ペア。

Sequelizeのデフォルトの動作では、ProductまたはInterestのいずれかが削除されると、ProductInterestのエントリも削除されます。要するに、あなたが望む削除の制約のように聞こえます。私はそれらの追加のonDelete制約を関連に渡すことの影響がどのようなものであるのかは分かりませんが、意図しない振る舞いを引き起こすことがわかったようです。

関連する問題