ほとんどの場合、関連付けは2つの異なるモデルの属性間(例えば、UserモデルとPetモデルの間の関係)で行われます。しかし、同じモデル内の2つの属性間の関係を持つことも可能です。これは再帰的関連付けと呼ばれます。
次のUserモデルを考えてみましょう。
// myApp/api/models/User.js
module.exports = {
attributes: {
firstName: {
type: 'string'
},
lastName: {
type: 'string'
},
// Add a singular reflexive association
bestFriend: {
model: 'user',
},
// Add one side of a plural reflexive association
parents: {
collection: 'user',
via: 'children'
},
// Add the other side of a plural reflexive association
children: {
collection: 'user',
via: 'parents'
},
// Add another plural reflexive association, this one via-less
bookmarkedUsers: {
collection: 'user'
}
}
};
上記のUserモデルの再帰的関連付けは、他の関連付けとまったく同じように機能します。単数のbestFriend属性は、別のユーザーのプライマリキー(または自己愛的な場合は同じユーザー!)に設定できます。parents属性とchildren属性は、.addToCollection()、.removeFromCollection()、および.replaceCollection()を使用して変更できます。すべての複数関連付けと同様に、一方に追加すると、関係はどちら側からでもアクセスできるようになることに注意してください。したがって、次を実行すると
// Add User #12 as a parent of User #23
await User.addToCollection(23, 'parents', 12);
// Find User #12 and populate its children
var userTwelve = await User.findOne(12).populate('children');
次のような結果が返されます。
{
id: 12,
firstName: 'John',
lastName: 'Doe',
bestFriend: null,
children: [
{
id: 23,
firstName: 'Jane',
lastName: 'Doe',
bestFriend: null
}
]
}
すべての「viaなし」の複数関連付けと同様に、再帰的なviaなし関連付けは、宣言された側からのみアクセスできます。上記の
Userモデルでは、User.findOne(55).populate('bookmarkedUsers')を実行して、ユーザー#55がブックマークしたすべてのユーザーを検索できますが、ユーザー#55をブックマークしたすべてのユーザーのリストを取得する方法はありません。これを行うには、viaプロパティを使用してbookmarkedUsersに結合される追加の属性(例えば、bookmarkedBy)が必要です。