data icon indicating copy to clipboard operation
data copied to clipboard

(4.x) Bad Relationship Schema Configuration can lead to misleading error messages

Open runspired opened this issue 2 years ago • 1 comments

When a record declares the same type + inverse field repeatedly error messages can be misleading because the relationship becomes misconfigured:

export default class Nest extends Model {
  @hasMany('modaction', { inverse: 'subject' }) blocking;
  @hasMany('modaction', { inverse: 'subject' }) muting;
}
export default class ModActionModel extends Model {
  @belongsTo('nest') subject;
  @belongsTo('nest') object;

The correct configuration here would be to set the inverse for all of these relationships to null. An example of a misleading error:

can only 'addToRelatedRecords' on a hasMany relationship. nest.blocking is a belongsT

Originally reported by holler on discord https://discord.com/channels/480462759797063690/485861149821239298/1059227968678920232

Better Dual FK Configuration

The underlying mistake here was that a ModAction.subject can only ever be one of blocking or muting, but not both. So there was an assumption that somehow multiple fields could act as foreign-keys. This is not something that EmberData supports: moreover, there is generally a better pattern for modeling these relationships (using a join model if necessary if blocking/muting is not universally known for a modaction).

export default class Nest extends Model {
  // nest-action is a join model that just points at a nest and a mod-action
  // with an isBlocking property, this join may not be needed, if so this
  // would just be `hasMany('nest'`
  @hasMany('nest-action', { inverse: 'subject' }) actions;
  
  @cached
  get blocking() {
    return Object.freeze(this.actions.filter(action => action.isBlocking));
  }
  
  @cached
  get muting() {
    return Object.freeze(this.actions.filter(action => !action.isBlocking));
  }
}

runspired avatar Jan 02 '23 23:01 runspired

partially resolved by #8555

runspired avatar Jul 12 '23 16:07 runspired