web-dev-qa-db-ja.com

hasMany Joinアソシエーションの続編

アプリケーションを拡張していて、以前にSequelizeで作成した2つのモデルを結合する必要があります。モデルは次のとおりです。

食事

sequelize.define('meal', {
    mealId: {
        type: DataTypes.INTEGER, 
        primaryKey: true,
        autoIncrement: true
    },
    quantity: {
        type: DataTypes.DECIMAL,
        allowNull: false
    },
    period: {
        type: DataTypes.INTEGER,
        allowNull: false
    }
})

フード

sequelize.define('food', {
    idFood: {
        type: DataTypes.INTEGER,
        primaryKey: true,
        autoIncrement: true
    },
    nameFood: {
        type: DataTypes.STRING,
        allowNull: false
    }
})

次の関係を追加しました。

db.food.hasMany(db.meal, {as : 'Food', foreignKey : 'idFood'});

この行は、食事にidFood列を追加します

Foodは、パン、米、豆など、多くの食品(duh)を含むテーブルですMealは、ユーザーが選択した食べ物を詳細とともに識別するテーブルです。

したがって、私の理解は、Mealに多くのFood(以前は)FoodMealとの関係を必要としませんでした。データを保持するだけで、最初にデータを入力しても変更されません。しかし、私がそれらに参加しようとしたとき:

db.meal.findAll({ include : [db.food] }).then(function (meals) {
    console.log(JSON.stringify(meals));
});

次のエラーが発生しました:

Unhandled rejection Error: food is not associated to meal!

誰かが私が何をすべきか説明できますか?私はそれが関係に関係していると思いますが、私が何をすべきかについての良い説明をドキュメント上で見つけることができませんでした。

ありがとうございました!

編集:ドキュメントを読む( 再度 )、例は理にかなっていますが、例はユーザーにタスクがあり、タスクはユーザーに属しているため、この例は私の状況に適用できるとは思いません。しかし、私の場合、多くの食事が同じ食品を異なる量(または異なるユーザー)で持つことができるため、食品は食事に属していません。

12
leofontes

問題は、関係を双方向で定義する必要があることです。現在、Sequelizeは、食品->食事からの取得方法を知っています。

db.food.hasMany(db.meal, {as : 'Food', foreignKey : 'idFood'});

しかしそれは食事から得る方法を知りません->食べ物。そのため、次のように同じ関係を逆に定義する必要があります。

db.meal.belongsTo(db.food, {foreignKey : 'idFood'});

最初のステートメントで既に定義したmeal.idFoodを定義するため、これはnewキーを追加しません。

これで実行できるはずです

db.meal.findAll({ include : [db.food] }).then(function (meals) {
    console.log(JSON.stringify(meals)); <-- each array element of meals should have an attribute `food`
});
16
Steffen Langer

関連付けでエイリアスを使用している場合({ as: 'Food' })includeステートメントでも使用する必要があります。

だからそれはそのようになるでしょう:

db.meal.findAll({ 
  include : [{
    model: db.food,
    as: 'Food'
  }]
}).then(function (meals) {
  console.log(JSON.stringify(meals));
});

アソシエーションにエイリアスが設定されている場合(asオプションを使用)、モデルを含めるときにこのエイリアスを指定する必要があります。上記のInstrumentsとして、ユーザーのツールがどのようにエイリアスされているかに注意してください。これを正しく行うには、読み込むモデルとエイリアスを指定する必要があります。

詳細 ここ

1
oleh.meleshko