1
votes

Using persistence.js I have two entities (Foo, Bar) forming a many-to-many relationship (N:M). So far I could only get it to work to add many "in one direction", i.e. one instance of Foo could add many Bars, but any instance of Bar used in this relationship cannot in turn have many Foos. But any new instance of Bar can have many Foos again. Is it possible and if so, how is it possible to add many entities "in both directions"? Or do I have to use a junction table as in RDBs (N:M => 1:N M:1 )?

var foo0, foo1, foo2, bar0, bar1, bar2

Foo = persistence.define( 'Foo', { val: 'TEXT' } )
Bar = persistence.define( 'Bar', { val: 'TEXT' } )
Foo.hasMany( 'bars', Bar, 'foo' )
Bar.hasMany( 'foos', Foo, 'bar' )

persistence.store.memory.config(persistence);
persistence.schemaSync();

foo0 = new Foo( { val : 'foo0' } )
foo1 = new Foo( { val : 'foo1' } )
foo2 = new Foo( { val : 'foo2' } )
bar0 = new Bar( { val : 'bar0' } )
bar1 = new Bar( { val : 'bar1' } )
bar2 = new Bar( { val : 'bar2' } )
foo1.bars.add( bar0 )
foo2.bars.add( bar0 ) // NOTE: already added to DB with statement above => does nothing
foo2.bars.add( bar1 )
bar1.foos.add( foo0 )
bar2.foos.add( foo0 ) // NOTE: already added to DB with statement above => does nothing
bar2.foos.add( foo1 )

persistence.flush( function () {
    Foo.all().each( function ( foo ) {
        foo.bars.list( function ( bars ) {
            console.log( "Foo " + foo.val + ": " )
            _.each( bars, function ( bar ) { console.log( bar.val ) } )
        } )
    } )

    Bar.all().each( function ( bar ) {
        bar.foos.list( function ( foos ) {
            console.log( "Bar " + bar.val + ": " )
            _.each( foos, function ( foo ) { console.log( foo.val ) } )
        } )
    } )

    Bar.all().list( function ( bars ) { foo0.bars = bars } )
    // => "Uncaught Error: not yet supported"
} )
1

1 Answers

2
votes

1. inverseProperties have to be the same

Foo.hasMany( 'bars', Bar, 'foos' )
Bar.hasMany( 'foos', Foo, 'bars' )

2. whenever one entity adds another entity, both are inserted in the database and automatically cross-referenced

  foo0 = new Foo { val: 'foo0: not used at all' }
  foo1 = new Foo { val: 'foo1: has bar0, not added by others' }
  foo2 = new Foo { val: 'foo2: cross-add bar1' }
  foo3 = new Foo { val: 'foo3: adds bar1 again' }
  foo4 = new Foo { val: 'foo4: adds multiple' }
  foo5 = new Foo { val: 'foo5: added by bar4 only' }
  bar0 = new Bar { val: 'bar0' }
  bar1 = new Bar { val: 'bar1: cross-add foo2, used again in foo3' }
  bar2 = new Bar { val: 'bar2: added by foo4 #1' }
  bar3 = new Bar { val: 'bar3: added by foo4 #2' }
  bar4 = new Bar { val: 'bar4: added by foo4 #3, has foo5'}

  foo1.bars.add bar0
  foo2.bars.add bar1
  foo3.bars.add bar1
  foo4.bars.add bar2
  foo4.bars.add bar3
  foo4.bars.add bar4

  bar1.foos.add foo2
  bar4.foos.add foo5

3. this is not the case however when using addAll(), which requires either to be added by persistence itself or by another entity

foo4b = new Foo { val : 'foo4b: copies bars from foo4' }
foo4.bars.list ( bars ) ->
        foo4b.bars.addAll bars
        persistence.add foo4b # choose one,
        # bar4.foos.add foo4b # either works