ほとんどの場合、関連付けは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
)が必要です。