PHPカンファレンスも終わったので、Crowi の資料作成から Crowi いじりに戻っている。
Mongoose のスキーマに「ObjectId
と共に ref
にモデル名」を付けておくと、populate()
メソッドで、そのモデルから ObjectId
のデータを自動で読み込んでくれるので便利で、Crowi の各モデルでは、ちょいちょい使われている。
いま作っている機能では「ObjectId
を保存するが、その対象となるモデルを動的に変えたい」場合が出て来た。その場合は ref
が使えないので、populate()
も使えないなーと思って、スキーマにモデル名を保存する項目を追加して、自前でそのモデルを読み込む処理を書かないとダメかなぁと思っていたのだけど、Mongoose のマニュアルを眺めていたら答えが載っていた。
refPath
を使うと、その path で保存されているデータ内容を元に populate()
してくれる。マニュアルに載っている下の例だと、connections.kind
に保存されるモデル名に対してデータ読み込みの処理を自動実行してくれるようだ。
var userSchema = new Schema({
name: String,
connections: [{
kind: String,
item: { type: ObjectId, refPath: 'connections.kind' }
}]
});
上記の例だと、connections
が配列になっているけど、特に配列である必要はなかった。同じレコードの中に保存されていれば問題ない様子。
「モデル名を保存しておく」という方法は変わらないけど、自前の population 実装が不要になったので良かった。マニュアルはちゃんと読んでおくべきだなぁ。