Foreign key field matching multiple conditions?


#1

Is it possible to have a foreign key field matching multiple conditions?

Given:

entity type Foo {
  fooOne: string
  fooTwo: string
}

entity type Bar {
  barOne: string
  barTwo: string
}

I need to define a field barObjs on type Foo such that the following is true:

var fooObj = Foo.fetch({
  include: "fooOne, fooTwo, barObjs"
}).at('objs[0]');

var result = Bar.fetch({
  filter: Filter.eq('barOne', fooObj.fooOne).and.eq('barTwo', fooObj.fooTwo)
}).at('objs');

expect(fooObj.barObjs).toEqual(result); // should pass

I’ve tried the following approaches unsuccessfully:

An fkey field with multiple conditions, but this causes a provisioning error:

entity type Foo {
  ...
  barObjs: [Bar](barOne, fooOne, barTwo, fooTwo) // E mismatched input ',' expecting ')'
}

A stored calc field with the intersection of multiple array fields. There doesn’t seem to be an intersection function, but maybe I’m missing something.

entity type Foo {
  ...
  oneBarObjs: [Bar](barOne, fooOne)
  twoBarObjs: [Bar](barTwo, fooTwo)
  barObjs: [Bar] stored calc 'intersection(oneBarObjs, twoBarObjs)' // Invalid Function call at line 1, column 0 in expression intersection(oneBarObjs, twoBarObjs).
}

Or maybe there’s a way to reference a field from Foo (via “this” or “self”) in an expression dot filter?

entity type Foo {
  ...
  oneBarObjs: [Bar](barOne, fooOne)
  barObjs: [Bar] stored calc 'oneBarObjs.(barTwo == this.fooTwo)'
  // Calc field barObjs in type -type-Foo.Foo references field fooTwo which
  // is not defined in type -type-Bar.Bar or any of its extension types
}

Is there a way I can achieve this functionality using just the type system?


#2

What you are describing here sounds like it is really a composite key. We do have support for composite keys that was added (beta) for a POC. This may work for this situation but I’m not sure as I only tested it for the POC needs. Please add a ticket for me to investigate to see if it can work as is (or with platform changes) and advise.

Other than that, you would need to use a stored calc to define the composite key fields as a concatenation with a delimiter. For example, in type Foo:

fooKey: string stored calc "fooOne + '#' + "entity type Foo {
  fooOne: string
  fooTwo: string

  fooKey: string stored calc "fooOne + '#' + fooTwo"
  barObjs: [Bar](barKey, fooKey)
}

entity type Bar {
  barOne: string
  barTwo: string

  barKey: string stored calc "barOne + '#' + barTwo"
  fooObjs: [Foo](barKey, fooKey)
}