22
33var _ = require ( 'lodash' )
44var utils = require ( './utils' )
5- var debug = require ( 'debug' ) ( 'loopback-component-jsonapi' )
5+ const linkRelatedModels = require (
6+ './utilities/relationship-utils'
7+ ) . linkRelatedModels
68
79module . exports = function ( app , options ) {
810 // get remote methods.
@@ -24,9 +26,7 @@ module.exports = function (app, options) {
2426 data = options . data
2527 model = utils . getModelFromContext ( ctx , app )
2628
27- relationships ( id , data , model )
28-
29- next ( )
29+ relationships ( model , id , data ) . then ( ( ) => next ( ) ) . catch ( err => next ( err ) )
3030 } )
3131
3232 // for create
@@ -41,144 +41,42 @@ module.exports = function (app, options) {
4141 id = ctx . result . data . id
4242 data = options . data
4343 model = utils . getModelFromContext ( ctx , app )
44- relationships ( id , data , model )
44+ return relationships ( model , id , data )
45+ . then ( ( ) => next ( ) )
46+ . catch ( err => next ( err ) )
4547 }
4648
4749 next ( )
4850 } )
4951}
5052
51- function relationships ( id , data , model ) {
52- if ( ! data || ! data . data || ! id || ! model || ! data . data . relationships ) {
53- return
53+ function extractIdsFromResource ( resource ) {
54+ if ( _ . isArray ( resource ) ) {
55+ return _ . map ( resource , 'id' )
5456 }
55-
56- _ . each ( data . data . relationships , function ( relationship , name ) {
57- var serverRelation = model . relations [ name ]
58- if ( ! serverRelation ) return
59- var type = serverRelation . type
60-
61- // don't handle belongsTo in relationships function
62- if ( type === 'belongsTo' ) return
63-
64- var modelTo = serverRelation . modelTo
65-
66- var fkName = serverRelation . keyTo
67-
68- if ( type === 'belongsTo' ) {
69- fkName = serverRelation . keyFrom
70- modelTo = serverRelation . modelFrom
71- }
72-
73- if ( ! modelTo ) {
74- return false
75- }
76-
77- var setTo = { }
78- setTo [ fkName ] = null
79- var where = { }
80- where [ fkName ] = id
81-
82- // remove all relations to the model (eg .: post/1)
83- if ( type !== 'belongsTo' ) {
84- modelTo . updateAll ( where , setTo , function ( err , info ) {
85- if ( err ) console . log ( err )
86- } )
87- }
88-
89- var idToFind = null
90-
91- if ( _ . isArray ( relationship . data ) ) {
92- // find all instance from the relation data eg
93- // [{type: "comments", id: 1}, {type: "comments", id: 2}]
94- _ . each ( relationship . data , function ( item ) {
95- idToFind = item . id
96-
97- if ( type === 'belongsTo' ) {
98- where [ fkName ] = item . id
99- idToFind = id
100- }
101-
102- updateRelation ( modelTo , idToFind , where )
103- } )
104-
105- if ( serverRelation . modelThrough ) {
106- var modelThrough = serverRelation . modelThrough
107- var key = keyByModel ( modelThrough , modelTo )
108- var data = { }
109- data [ fkName ] = id
110- var stringIds = false
111-
112- var payloadIds = _ . map ( relationship . data , function ( item ) {
113- if ( typeof item . id === 'string' ) {
114- stringIds = true
115- }
116- return item . id
117- } )
118-
119- modelThrough . find ( { where : data , fields : key } , function (
120- err ,
121- instances
122- ) {
123- if ( err ) return
124- var serverIds = _ . map ( instances , function ( instance ) {
125- return stringIds ? instance [ key ] . toString ( ) : instance [ key ]
126- } )
127- // to delete
128- var toDelete = _ . difference ( serverIds , payloadIds )
129- _ . each ( toDelete , function ( id ) {
130- data [ key ] = id
131- modelThrough . destroyAll ( data )
132- } )
133- // new
134- var newAssocs = _ . difference ( payloadIds , serverIds )
135- _ . each ( newAssocs , function ( id ) {
136- data [ key ] = id
137- modelThrough . create ( data )
138- } )
139- } )
140- }
141- } else {
142- if ( relationship . data === null ) {
143- where [ fkName ] = null
144- updateRelation ( model , id , where )
145- return
146- }
147-
148- idToFind = relationship . data . id
149-
150- if ( type === 'belongsTo' ) {
151- idToFind = id
152- where [ fkName ] = relationship . data . id
153- }
154- // relationship: {data: {type: "comments": id: 1}}
155- updateRelation ( modelTo , idToFind , where )
156- }
157- } )
57+ return _ . get ( resource , 'id' , null )
15858}
15959
160- // if the instance exist, then update it (create relationship),
161- // according to JSON API spec we MUST NOT create new ones
162- function updateRelation ( model , id , data ) {
163- model . findById ( id , function ( err , instance ) {
164- if ( err ) console . log ( err )
60+ function relationships ( model , id , payload ) {
61+ if ( ! id || ! model ) return
62+ const relationships = _ . get ( payload , 'data.relationships' , { } )
16563
166- if ( instance ) {
167- instance . updateAttributes ( data )
168- }
169- } )
170- }
64+ return Promise . all (
65+ Object . keys ( relationships ) . map ( relationName => {
66+ const relationship = relationships [ relationName ]
67+ const relationDefn = model . relations [ relationName ]
68+ if ( ! relationDefn ) return
17169
172- function keyByModel ( assocModel , model ) {
173- var key = null
174- _ . each ( assocModel . relations , function ( relation ) {
175- if ( relation . modelTo . modelName === model . modelName ) {
176- key = relation . keyFrom
177- }
178- } )
70+ const type = relationDefn . type
71+ const modelTo = relationDefn . modelTo
17972
180- if ( key === null ) {
181- debug ( 'Can not find relation for ' + model . modelName )
182- }
183- return key
73+ // don't handle belongsTo in relationships function
74+ if ( ! modelTo || type === 'belongsTo' ) return
75+
76+ const data = extractIdsFromResource ( relationship . data )
77+ const from = { model, id }
78+ const to = { model : modelTo , data }
79+ return linkRelatedModels ( relationName , from , to )
80+ } )
81+ )
18482}
0 commit comments