Vincit/objection.js

$fetchGraph returning empty array when it should return data

Open

#2.258 aberto em 13 de abr. de 2022

Ver no GitHub
 (7 comments) (0 reactions) (0 assignees)JavaScript (663 forks)batch import
bughelp wanted

Métricas do repositório

Stars
 (7.146 stars)
Métricas de merge de PR
 (Nenhuma PRs mesclada em 30d)

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?

Guia do colaborador