admin管理员组

文章数量:1427287

I have the following model defined:

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",
        },
      },
    };
  }
}

And to query a User with their email addresses would require withGraphFetched() to be explicitly run every time as:

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

I haven't been able to figure out what to write in the Model definition to make this possible, and I don't see any such examples online. Is it possible to ALWAYS have withGraphFetched("emails") automatically included in the query so it doesn't have to be explicitly written out every time?

I have the following model defined:

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",
        },
      },
    };
  }
}

And to query a User with their email addresses would require withGraphFetched() to be explicitly run every time as:

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

I haven't been able to figure out what to write in the Model definition to make this possible, and I don't see any such examples online. Is it possible to ALWAYS have withGraphFetched("emails") automatically included in the query so it doesn't have to be explicitly written out every time?

Share Improve this question edited Mar 4, 2021 at 10:39 Rashomon 6,8124 gold badges39 silver badges80 bronze badges asked Apr 30, 2020 at 3:56 RajRaj 1,66521 silver badges32 bronze badges
Add a ment  | 

1 Answer 1

Reset to default 4

Such thing doesnt exist. Maybe you could create the logic in the beforeFind hook adding the eager loader to the knex instance, but it could generate a lot of undesired and strange side-effects.

The normal practice is adding a method to that specific case:

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)
  }
}

Then you can just:

const myUser = await User.getUser(id)

本文标签: