如何为 objection.js 中的所有模型查询自动包含 `.withGraphFetched()`

How to automatically include `.withGraphFetched()` for all queries of model in objection.js

我定义了以下模型:

import db from "../connection.js";
import objection from "objection";
const { Model } = objection;

Model.knex(db);

class User extends Model {
  static get tableName() {
    return "users";
  }

  static get relationMappings() {
    return {
      emails: {
        relation: Model.HasManyRelation,
        modelClass: Email,
        join: {
          from: "users.id",
          to: "emails.user_id",
        }
      }
    }
  }
}

class Email extends Model {
  static get tableName() {
    return "emails";
  }

  static get relationMappings() {
    return {
      user: {
        relation: Model.BelongsToOneRelation,
        modelClass: User,
        join: {
          from: "emails.user_id",
          to: "users.id",
        },
      },
    };
  }
}

并且要使用他们的电子邮件地址查询 User 需要 withGraphFetched() 每次都显式 运行 为:

const myUser = await User.query().withGraphFetched("emails").findById(1)

我一直无法弄清楚在模型定义中写什么才能使这成为可能,而且我在网上也没有看到任何此类示例。是否可以始终将 withGraphFetched("emails") 自动包含在查询中,这样就不必每次都明确写出?

这样的东西是不存在的。也许您可以在 beforeFind 挂钩中创建逻辑,将 eager loader 添加到 knex 实例,但它可能会产生许多不希望的和奇怪的副作用。

通常的做法是为该特定案例添加一个方法:

class User extends Model {
  static get tableName() {
    return "users";
  }

  static get relationMappings() {
    return {
      emails: {
        relation: Model.HasManyRelation,
        modelClass: Email,
        join: {
          from: "users.id",
          to: "emails.user_id",
        }
      }
    }
  }

  static async getUser (id) { // Or maybe getUserWithEmails
      return await this.query().withGraphFetched("emails").findById(id)
  }
}

那么你可以:

const myUser = await User.getUser(id)