Vincit/objection.js

$fetchGraph returning empty array when it should return data

Open

#2 258 ouverte le 13 avr. 2022

Voir sur GitHub
 (7 commentaires) (0 réactions) (0 assignés)JavaScript (663 forks)batch import
bughelp wanted

Métriques du dépôt

Stars
 (7 146 stars)
Métriques de merge PR
 (Aucune PR mergée en 30 j)

Description

I tried asking this in Gitter several weeks ago but didn't get very far.

I'm having a strange issue with $fetchGraph() that I'm sure is something I'm doing wrong. Given these (simplified) models:

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

  static get relationMappings() {
    return {
      hardwareTokenRegistrations: {
        relation: HasManyRelation,
        modelClass: HardwareTokenRegistration,
        join: {
          from: 'users.id',
          to: 'hardware_token_registrations.user_id',
        },
      },
    };
  }
};

class HardwareTokenRegistration extends Model {
  static get tableName() {
    return 'hardware_token_registrations';
  }

  static get relationMappings() {
    return {
      hardwareToken: {
        relation: HasOneRelation,
        modelClass: HardwareToken,
        join: {
          from: 'hardware_token_registrations.hardware_token_id',
          to: 'hardware_tokens.id',
        },
      },
      user: {
        relation: HasOneRelation,
        modelClass: User,
        join: {
          from: 'hardware_token_registrations.user_id',
          to: 'users.id',
        },
      },
    };
  }
};

Schema:

mfa=# \d users
                                       Table "public.users"
   Column   |           Type           | Collation | Nullable |              Default
------------+--------------------------+-----------+----------+-----------------------------------
 id         | integer                  |           | not null | nextval('users_id_seq'::regclass)
 uuid       | character varying(255)   |           | not null |
 username   | character varying(255)   |           | not null |
 created_at | timestamp with time zone |           |          | CURRENT_TIMESTAMP
 updated_at | timestamp with time zone |           |          | CURRENT_TIMESTAMP
Indexes:
    "users_pkey" PRIMARY KEY, btree (id)
    "users_username_index" btree (username)
    "users_username_unique" UNIQUE CONSTRAINT, btree (username)
    "users_uuid_index" btree (uuid)
    "users_uuid_unique" UNIQUE CONSTRAINT, btree (uuid)
Referenced by:
    TABLE "hardware_token_registrations" CONSTRAINT "hardware_token_registrations_user_id_foreign" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
... others removed ...

mfa=# \d hardware_token_registrations;
                                          Table "public.hardware_token_registrations"
      Column       |           Type           | Collation | Nullable |                         Default
-------------------+--------------------------+-----------+----------+----------------------------------------------------------
 id                | integer                  |           | not null | nextval('hardware_token_registrations_id_seq'::regclass)
 user_id           | integer                  |           | not null |
 hardware_token_id | integer                  |           | not null |
 validation_code   | character varying(255)   |           | not null |
 created_at        | timestamp with time zone |           |          | CURRENT_TIMESTAMP
 updated_at        | timestamp with time zone |           |          | CURRENT_TIMESTAMP
Indexes:
    "hardware_token_registrations_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
    "hardware_token_registrations_hardware_token_id_foreign" FOREIGN KEY (hardware_token_id) REFERENCES hardware_tokens(id)
    "hardware_token_registrations_user_id_foreign" FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE

I have an instance of User and want to fetch its HardwareTokenRegistrations:

let user = await User.query().findById(1);
let userWithRegistrations = await user.$fetchGraph('hardwareTokenRegistrations');

/* 
returns:

User {
  id: 1,
  uuid: 'grahamb',
  username: 'grahamb',
  createdAt: 2021-12-16T23:57:14.000Z,
  updatedAt: 2022-03-30T20:56:59.239Z,
  hardwareTokenRegistrations: []
}
*/

Note that the hardwareTokenRegistrations array is empty. In reality, there is one related record.

The query generated by the $fetchGraph query is:

{
  method: 'select',
  options: {},
  timeout: false,
  cancelOnTimeout: false,
  bindings: [ 1 ],
  __knexQueryUid: 'qCYLMv1SfgVFnMl4FCa_p',
  sql: 'select "hardware_token_registrations".* from "hardware_token_registrations" where "hardware_token_registrations"."user_id" in (?)'
}

If I run the same query manually against the database, the records are retrieved:

mfa=# select "hardware_token_registrations".* from "hardware_token_registrations" where "hardware_token_registrations"."user_id" in (1);
-[ RECORD 1 ]-----+-----------------------------
id                | 1
user_id           | 1
hardware_token_id | 4
validation_code   | 851728
created_at        | 2021-12-16 23:57:14+00
updated_at        | 2022-03-14 21:52:58.75705+00

I can't figure out what I'm doing wrong here. Any clues?

Guide contributeur