2016-12-06 17 views
0

私は、お互いに関係のない2つの関連するテーブル(参照&ユーザ)を持つ親テーブル(ドキュメント)をクエリしようとしていますが、親テーブルこのように正しくは私が探していますデータ出力のようなSQLでは、このクエリはなります2つのテーブルでネストされた関連付けを続ける

select * 
from `document` 
left join `user` 
on `document`.`user_id` = `user`.`user_id` 
left join `reference` 
on `document`.`reference_id` = `reference`.`reference_id` 
where `user`.`organization_id` = 1; 

をただし、ネストされている団体は、クエリが動作するために階層順に関係しなければなりません。ネストされたアソシエーションは互いに関連していないので、アソシエーションエラーが発生します。どうすればこのエラーを回避できますか? required: falseはこれに影響を及ぼしますか?

models.Document.findAll({ 
    order: 'documentDate DESC', 
    include: [{ 
    model: models.User, 
    where: { organizationId: req.user.organizationId }, 
    include: [{ 
     model: models.Reference, 
    }] 
    }], 
}) 

エラー

Unhandled rejection Error: reference is not associated to user!

団体

Document

associate: function(db) { 
    Document.belongsTo(db.User, {foreignKey: 'user_id'}), 
    Document.belongsTo(db.Reference, { foreignKey: 'reference_id'});; 
} 

Reference

associate: function(db){ 
    Reference.hasMany(db.Document, { foreignKey: 'reference_id' }); 
} 

は、私はちょうど代わりにクエリをチェーンべきでしょうか?

+0

あなたは 'underscored:true'を指定しているようですが、cameCaseの名前は' organization_id'と 'organizationId'などです。 – doublesharp

答えて

1

クエリを複製する場合(可能な限り)、次のクエリを使用します。ユーザーincludewhereはの一致を削除するためにのみ使用され、User.organization_idは一致しませんが、Documentは引き続き返されます。 User.organization_idが一致しない文書を省略する場合は、required: trueを使用します。

User <- Document -> Reference

models.Document.findAll({ 
    // this is an array of includes, don't nest them 
    include: [{ 
    model: models.User, 
    where: { organization_id: req.user.organization_id }, // <-- underscored HERE 
    required: true, // <-- JOIN to only return Documents where there is a matching User 
    }, 
    { 
    model: models.Reference, 
    required: false, // <-- LEFT JOIN, return rows even if there is no match 
    }], 
    order: [['document_date', 'DESC']], // <-- underscored HERE, plus use correct format 
}); 
+0

更新これはまさに私が探していたものです!私は、親テーブルに関連付けられている複数のテーブルを結合する方法を把握しようとしていましたが、これは問題を解決しました。最初の配列の中に別のインクルードを入れ子にするのではなく、インクルード配列内に両方を入れ子にすることをどのように知っていましたか?私はドキュメントやコミュニティの回答の中でこれを見つけたことは信じられません。 – cphill

+0

データモデルによって異なります。前にも言及したように(最初の答えが間違っていた理由)、それらを入れ子にして関係のタイプを 'Document-> User-> Reference'に変更すると、本当に' Document-> User' + 'Document-> Reference '。 – doublesharp

0

エラーがUserモデルがReferenceモデルに関連付けられていないが、あなたの説明にDocumentReferenceモデルのみ定義が存在することを示すされています。これらのテーブルは、クエリの中でincludeオプションを使用して結合しているため、関連付けられていることを確認する必要があります。技術的にはforeignKeyが必要ではありません。デフォルト値を指定しています。

あなたはおそらくあなたのモデル定義にunderscored: trueを設定するようにそれはまた見えますので、あなたのクエリはこれを反映すべきであるReference->User関連

associate: function(db) { 
    // belongsTo()? maybe another relationship depending on your data model 
    Reference.belongsTo(db.User, {foreignKey: 'user_id'}); 

    Reference.hasMany(db.Document, { foreignKey: 'reference_id' }); 
} 

を追加します。さらに、LEFT JOINを実行する場合はincluderequired: falseを指定する必要があります。そうでない場合は通常のJOINとなり、includeモデルでは一致する行のみが返されます。 order形式も間違っています。値の配列である必要があります。model.document_date DESCで並べ替える場合は、order: [['document_date', 'DESC']]を使用してください。あなたはそれがあなたのコンソールで実行されているすべてのクエリが表示されます

適切なクエリー引数

models.Document.findAll({ 
    order: [['document_date', 'DESC']], // <-- underscored HERE, plus use correct format 
    include: [{ 
    model: models.User, 
    where: { organization_id: req.user.organization_id }, // <-- underscored HERE 
    required: false, // <-- LEFT JOIN 
    include: [{ 
     model: models.Reference, 
     required: false, // <-- LEFT JOIN 
    }] 
    }], 
}); 

それでも問題が解決されない場合、お使いのSequelize接続でlogging: console.logを設定することでログを有効にしてみてください。

+0

詳細なコメントをいただきありがとうございます。私はUserモデルについて詳細を追加していないことに気付きました。私が簡単なリファレンスの外に置いた理由は、そのモデルに関連する他の2つのテーブル(ドキュメントとリファレンス)に関連するものがないからです。私の質問は、外部キーなしでテーブルを関連付けることは、協会がすべきことの目的を破ることではありませんか? FKでテーブル間の関係?参照はユーザーとは直接関係していないため、生のクエリはより良いルートになるでしょうか? – cphill

+0

あなたのクエリは、関連が 'Document-> User-> Reference'であることを反映しています。 – doublesharp

+0

'Document-> User'と' Document-> Reference'を問い合わせるのですか? – doublesharp

0

あなたの問題ではなく、カラムのuser_idは 'と「REFERENCE_ID」の書類上のプライマリキーにリンクしようとし、組合かもしれないと私には思えます。あなたはテーブル属性を投稿していないので、私はこれを間違って理解しているかもしれません。

文書の関連付けは問題ありません。あなたがクエリを見ることができるように

ドキュメント

associate: function(db) { 
    Document.belongsTo(db.User, {foreignKey: 'user_id'}), //key in documents 
    Document.belongsTo(db.Reference, { foreignKey: 'reference_id'}); //key in documents 
} 

ユーザー

associate: function(db) { 
    User.belongsTo(db.Document, { 
    foreignKey: 'id', //Key in User 
    targetKey: 'user_id' //Key in Documents 
    }), 
} 

リファレンス

また
associate: function(db) { 
    Reference.belongsTo(db.Document, { 
     foreignKey: 'id',   //Key in reference 
     targetKey: 'reference_id' //Key in Documents 
    }), 
} 

はdebbugingのロギングを使用することを検討してください。

関連する問題