出力するjsonにテーブルにない項目を追加したいとき、Modelにgetterを追加することになります。(参考)
しかし、getter内でasyncを使いたい時(例えば別のテーブルから値を参照したい時)、上記の方法では出来ないのでhookを使うことになります。
hookを使った方法のサンプルがなかったので記事として残しておきます。
前提
- adonis.js 4.1
サンプルコード
Modelはすでに作ってあるとします。
次にHookを作成します。
adonis make:hook PostHook
Hookは /app/Models/Hooks
に作られます。
次に Hook を編集します。
/app/Models/Hooks/PostHook.js
'use strict'
const Code = use('App/Models/Code') // コードマスタ
const PostHook = exports = module.exports = {}
PostHook.computedFields = async (modelInstance) => {
if (Array.isArray(modelInstance)) {
modelInstance = await Promise.all(computedFields.map(bindCodeNames))
} else {
modelInstance = await computedFields(modelInstance)
}
}
async function computedFields(model) {
// ここで追加したいFieldを代入していく
model.status_name = await Code.get('status', model.status)
return model
}
最後にModel側に追記します。
/app/Models/Post
'use strict'
const Model = use('Model')
class Post extends Model {
static boot() {
super.boot()
// 以下3つを追加
this.addHook('afterFind', 'PostHook.computedFields')
this.addHook('afterFetch', 'PostHook.computedFields')
this.addHook('afterPaginate', 'PostHook.computedFields')
}
}
動作サンプル
start/routes.js
const Post = use('App/Models/Post')
Route.get('post/:id', ({params, response}) => {
const post = Post.findOrFail(params.id)
return response.send(post) // { ..., status: 1, status_name: '公開' }
})
追記 2019.06.11
この方法でgetterを追加した場合、更新時( save()
時)、追加したgetterの名前のカラムが無いとSQLでエラーを吐かれます。そのため、更新時に要素を削除するという処理を入れる必要が出てきます。
以下、処理の例です。
/app/Models/Hooks/PostHook.js
// 追加
PostHook.removeComputedFields = (modelInstance) => {
modelInstance = removeComputedFields(modelInstance)
}
function removeComputedFields(model) {
delete model.$attributes.status_name
return model
}
/app/Models/Post.js
class Post extends Model {
static boot() {
super.boot()
this.addHook('afterFind', 'PostHook.computedFields')
this.addHook('afterFetch', 'PostHook.computedFields')
this.addHook('afterPaginate', 'PostHook.computedFields')
// 追加
this.addHook('beforeUpdate', 'PostHook.removeComputedFields')
}
}
delete
で無理やりプロパティを消してるので、なんか他にいい方法無いのかなと思うのですが調べても出てこない感じでした……。
adonis.jsはJavascript(Node.js)製のWebフレームワーク。laravelに似ており全てをjavascriptで書くことができます。
日本でも広まれー!