Skip to content

multiple belongsTo relationships between 2 entities lead to unintended outcome #363

@CarstenRuetz

Description

@CarstenRuetz

Environment

{
  "name": "test1",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "serve": "vue-cli-service serve",
    "build": "vue-cli-service build",
    "test:unit": "vue-cli-service test:unit",
    "test:e2e": "vue-cli-service test:e2e",
    "lint": "vue-cli-service lint"
  },
  "dependencies": {
    "@capacitor/app": "1.1.1",
    "@capacitor/core": "3.5.1",
    "@capacitor/haptics": "1.1.4",
    "@capacitor/keyboard": "1.2.2",
    "@capacitor/status-bar": "1.0.8",
    "@ionic/vue": "^6.0.0",
    "@ionic/vue-router": "^6.0.0",
    "axios": "^0.27.2",
    "core-js": "^3.6.5",
    "date-fns": "^2.28.0",
    "dayjs": "^1.11.5",
    "eslint-config-typescript": "^3.0.0",
    "install": "^0.13.0",
    "ionic-logging-service": "^14.0.0",
    "lodash": "^4.17.21",
    "npm": "^8.13.1",
    "pinia": "^2.0.14",
    "pinia-orm": "^1.0.0",
    "swiper": "^8.3.2",
    "tslint": "^6.1.3",
    "vue": "^3.2.21",
    "vue-promised": "^2.2.0",
    "vue-router": "^4.0.12"
  },
  "devDependencies": {
    "@capacitor/cli": "3.5.1",
    "@ionic/cli": "6.19.1",
    "@types/jest": "^27.0.2",
    "@types/lodash": "^4.14.182",
    "@typescript-eslint/eslint-plugin": "^5.26.0",
    "@typescript-eslint/parser": "^5.26.0",
    "@vue/cli-plugin-babel": "~5.0.0-rc.1",
    "@vue/cli-plugin-e2e-cypress": "~5.0.0-rc.1",
    "@vue/cli-plugin-eslint": "~5.0.0-rc.1",
    "@vue/cli-plugin-router": "~5.0.0-rc.1",
    "@vue/cli-plugin-typescript": "~5.0.0-rc.1",
    "@vue/cli-plugin-unit-jest": "~5.0.0-rc.1",
    "@vue/cli-service": "~5.0.0-rc.1",
    "@vue/test-utils": "^2.0.0-rc.16",
    "@vue/vue3-jest": "^27.0.0-alpha.3",
    "babel-jest": "^27.3.1",
    "cypress": "^8.7.0",
    "eslint": "^8.17.0",
    "eslint-config-airbnb-base": "^15.0.0",
    "eslint-plugin-import": "^2.26.0",
    "eslint-plugin-vue": "^9.4.0",
    "jest": "^27.3.1",
    "ts-jest": "^27.0.7",
    "typescript": "^4.3.5"
  },
  "description": "An Ionic project",
  "prettier": {
    "singleQuote": true,
    "printWidth": 120
  }
}

Reproduction


class EventItem extends Model {
  static entity = 'eventitem';
  static primaryKey = ['id'];

  static fields() {
    return {
      id: this.uid(),
      name: this.string(''),

      participants: this.belongsToMany(People, EventItemPeople, 'eventitem_id', 'people_id', 'id', 'id'),
      // providers relationship seems to overwrite participants relationship
      providers: this.belongsToMany(People, EventItemPeople2, 'eventitem_id2', 'people_id2', 'id', 'id'),
      animals: this.belongsToMany(Animal, EventItemAnimal, 'eventitem_id', 'animal_id', 'id', 'id'),
    };
  }
}

class EventItemPeople extends Model {
  static entity = 'eventitempeople';

  static primaryKey = ['eventitem_id', 'people_id'];
  //   static primaryKey = ['id'];

  static fields() {
    return {
      id: this.uid(),
      eventitem_id: this.uid(),
      people_id: this.uid(),
    };
  }
}

class EventItemPeople2 extends Model {
  static entity = 'eventitempeople2';

  //   static primaryKey = ['eventitem_id1', 'people_id1'];
  static primaryKey = ['id'];

  static fields() {
    return {
      id: this.uid(),
      eventitem_id2: this.uid(),
      people_id2: this.uid(),
    };
  }
}

class People extends Model {
  static entity = 'people';

  static primaryKey = ['id'];

  static fields() {
    return {
      id: this.uid(),
      name: this.string(''),
    };
  }
}

class Animal extends Model {
  static entity = 'animals';

  static primaryKey = ['id'];

  static fields() {
    return {
      id: this.uid(),
      name: this.string(''),
    };
  }
}

class EventItemAnimal extends Model {
  static entity = 'eventitemanimal';

  //   static primaryKey = ['eventitem_id1', 'people_id1'];
  static primaryKey = ['id'];

  static fields() {
    return {
      id: this.uid(),
      eventitem_id: this.uid(),
      animal_id: this.uid(),
    };
  }
}

export { EventItem, People };

    useRepo(EventItem).save([
      {
        id: -1,
        name: 'item 1',
        participants: [{ id: -1000, name: 'Carsten' }],
        providers: [{ id: -1001, name: 'Peter' }],
        animals: [{ id: -2000, name: 'dog 1' }],
      },
    ]);

Screenshot 2022-09-19 at 18 00 53

Describe the bug

First of all: thanks for the great work on this!

I ran across a problem with multiple n-m relationships between two entities EventItem and People.
People can be participants of EventItems and they can also be providers to EventItems.

It seems to me that the relationship that is declared last actually wins. So in the example above, there will be only the eventitempeople2 relationship. According to the vue dev-tools, the participant "Carsten" with id -1000 is inserted into the eventitempeople2 relationship.
Switching the participant and provider relationships, creates exactly the opposite effect.

I added the Animals relationship just to check whether a different m - n relationship to another entity does work - and it does.
This is a reduced example of the data model I actually used. In that model the second relationship to People ran via another entity in-between EventItem and Participant. But this caused the same issue.

Any ideas?

Additional context

No response

Logs

No response

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions