2
2
3
3
var _ = require ( 'lodash' )
4
4
var utils = require ( './utils' )
5
- var debug = require ( 'debug' ) ( 'loopback-component-jsonapi' )
5
+ const linkRelatedModels = require (
6
+ './utilities/relationship-utils'
7
+ ) . linkRelatedModels
6
8
7
9
module . exports = function ( app , options ) {
8
10
// get remote methods.
@@ -24,9 +26,7 @@ module.exports = function (app, options) {
24
26
data = options . data
25
27
model = utils . getModelFromContext ( ctx , app )
26
28
27
- relationships ( id , data , model )
28
-
29
- next ( )
29
+ relationships ( model , id , data ) . then ( ( ) => next ( ) ) . catch ( err => next ( err ) )
30
30
} )
31
31
32
32
// for create
@@ -41,144 +41,42 @@ module.exports = function (app, options) {
41
41
id = ctx . result . data . id
42
42
data = options . data
43
43
model = utils . getModelFromContext ( ctx , app )
44
- relationships ( id , data , model )
44
+ return relationships ( model , id , data )
45
+ . then ( ( ) => next ( ) )
46
+ . catch ( err => next ( err ) )
45
47
}
46
48
47
49
next ( )
48
50
} )
49
51
}
50
52
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' )
54
56
}
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 )
158
58
}
159
59
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' , { } )
165
63
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
171
69
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
179
72
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
+ )
184
82
}
0 commit comments