Skip to content

Commit

Permalink
Add different way to define relations on models
Browse files Browse the repository at this point in the history
  • Loading branch information
stefanmajoor committed Nov 22, 2023
1 parent f1462a1 commit 7cfa79a
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
21 changes: 20 additions & 1 deletion src/Model.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import Store from './Store';
import { invariant, snakeToCamel, camelToSnake, relationsToNestedKeys, forNestedRelations } from './utils';
import Axios from 'axios';
import {Relation} from "./Relations";

function concatInDict(dict, key, value) {
dict[key] = dict[key] ? dict[key].concat(value) : value;
Expand Down Expand Up @@ -172,7 +173,12 @@ export default class Model {

// Find all attributes. Not all observables are an attribute.
forIn(this, (value, key) => {
if (!key.startsWith('__') && isObservableProp(this, key)) {

// Register relations
if (value instanceof Relation) {
this.__relations[key] = value.model;
this[key] = undefined
} else if (!key.startsWith('__') && isObservableProp(this, key)) {
invariant(
!FORBIDDEN_ATTRS.includes(key),
`Forbidden attribute key used: \`${key}\``
Expand Down Expand Up @@ -966,4 +972,17 @@ export default class Model {
this[currentRel].clear();
});
}

/**************
* New way of doing relations
*************/
__relations = {}

relation(modelOrSTore) {
return new Relation(modelOrSTore)
}

relations() {
return this.__relations;
}
}
11 changes: 11 additions & 0 deletions src/Relations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export class Relation {
__toModel = null;

constructor(toModel) {
this.__toModel = toModel
}

get model() {
return this.__toModel
}
}
59 changes: 59 additions & 0 deletions src/__tests__/NewRelation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Kind, Person, PersonStore} from "./fixtures/Animal";
import {observable} from "mobx";
import Model from "../Model";
import {BinderApi} from "../index";

class Animal extends Model {
urlRoot = '/api/animal/';
api = new BinderApi();
static backendResourceName = 'animal';
@observable id = null;
@observable name = '';

@observable kind = this.relation(Kind);

@observable owner = this.relation(Person);

@observable pastOwner = this.relation(PersonStore)
}

describe('Model with new way of defining relations', () => {
test('Initialize model with valid data', () => {
const animal = new Animal({})

Check warning on line 22 in src/__tests__/NewRelation.js

View workflow job for this annotation

GitHub Actions / check (14)

'animal' is assigned a value but never used
});

test('Relation should not be initialized by default', () => {
const animal = new Animal();

expect(animal.kind).toBeUndefined();
});

test('Initialize one-level relation', () => {
const animal = new Animal(null, {
relations: ['kind'],
});

expect(animal.kind).toBeInstanceOf(Kind);
});
test('Initialize multiple relations', () => {
const animal = new Animal(null, {
relations: ['kind', 'owner'],
});

expect(animal.kind).toBeInstanceOf(Kind);
expect(animal.owner).toBeInstanceOf(Person);
});

test('Non existent relation should throw an error', () => {
expect(() => {
return new Animal(null, {
relations: ['ponyfoo'],
});
}).toThrow('Specified relation "ponyfoo" does not exist on model.');
});


})



0 comments on commit 7cfa79a

Please sign in to comment.