雑文発散

«前の日記(2016-11-05) 最新 次の日記(2016-11-07)» 編集
過去の日記

2016-11-06 [長年日記]

[Crowi] Mongoose の Dynamic References がやりたいことだった(マニュアル読め案件)

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 実装が不要になったので良かった。マニュアルはちゃんと読んでおくべきだなぁ。