4

I'm kind of confused about what relationMappings do inside a Objection.js Model class.

I thought once we setup the relationMapping inside a Model, we will get related data in every query. But, it turns out that I still only the Model properties itself.

Is there anything else I should use to get related data in query?

Arel Lin
  • 908
  • 2
  • 13
  • 24

1 Answers1

7

Relation mappings gives model semantics how relations can be fetched when they are needed. It would be really bad for performance to always query all related rows in addition to main table's row. When you create relation mappings to model, you will not need to write joins manually every time you need to query relations. Also they enable many other objection features, which requires information how row relations goes in DB.

To use relation mappings in query Objection.js requires that within every query you must tell which relations you want to fetch with the main row with .withGraphFetched or .withGraphJoined methods https://vincit.github.io/objection.js/guide/query-examples.html#eager-loading

for example:

class Person extends Model {
  static get tableName() {
    return 'persons';
  }

  static get relationMappings() {
    return {
      pets: {
        relation: Model.HasManyRelation,
        modelClass: Animal,
        join: {
          from: 'persons.id',
          to: 'animals.ownerId'
        }
      }
    };
  }
}


const people = await Person.query().withGraphFetched('pets');

// Each person has the `pets` property populated with Animal objects related
// through the `pets` relation.
console.log(people[0].pets[0].name);
console.log(people[0].pets[0] instanceof Animal); // --> true

Mappings are also used when you insert nested object data with .insertGraph so that related objects are inserted to related tables and foreign key references etc. are automatically filled according to relation mapping declarations.

There are many other places where those are used, but I hope this gives a rough idea why they exist.

Mikael Lepistö
  • 18,909
  • 3
  • 68
  • 70
  • Best answer I've ever had! Just want to clarify this sentence: `When you create relation mappings to model, you will not need to write joins manually every time you need to query relations` Even though I use relation mappings in the Model, I still need to use `withGraphFetched` method to get the related data, else it won't show, am I right? – Arel Lin Mar 04 '20 at 08:41
  • @ArelLin yes, correct. `.withGraphFetched` will not work without mappings. – Mikael Lepistö Mar 04 '20 at 11:58
  • Awesome, now I understand the concept, thanks for the great help! – Arel Lin Mar 04 '20 at 13:29
  • 1
    Also we can use `.relate()` to insert a value to the relation mapping, which is super easy to use, as explained in the official guide. – newguy Jun 22 '20 at 15:46