@@ -31,13 +31,18 @@ class QueryOptions {
31
31
options . limit = this . _limit ;
32
32
}
33
33
34
- if ( this . _restrictFieldsOnRootModel && this . _requestedFields . size ) {
34
+ if ( this . _requestedFields . size && ! this . _hasRequestedSmartFields ) {
35
35
// Restricting loaded fields on the root model is opt-in with sequelize to avoid
36
36
// side-effects as this was not supported historically and it would probably break
37
37
// smart fields.
38
38
// @see https://github.com/ForestAdmin/forest-express-sequelize/blob/7d7ad0/src/services/resources-getter.js#L142
39
39
40
- options . attributes = [ ...this . _requestedFields ] . filter ( ( s ) => ! s . includes ( '.' ) ) ;
40
+ const simpleSchemaFields = this . _schema . fields
41
+ . filter ( ( field ) => ! field . reference )
42
+ . map ( ( field ) => field . field ) ;
43
+ options . attributes = [ ...this . _requestedFields ]
44
+ . filter ( ( field ) => simpleSchemaFields . includes ( field ) ) ;
45
+ options . attributes . push ( ...this . _schema . primaryKeys ) ;
41
46
}
42
47
43
48
return SequelizeCompatibility . postProcess ( this . _model , options ) ;
@@ -67,7 +72,7 @@ class QueryOptions {
67
72
68
73
/** Compute sequelize query `.include` property */
69
74
get _sequelizeInclude ( ) {
70
- const fields = [ ...this . _requestedFields , ...this . _neededFields ] ;
75
+ const fields = [ ...this . _requestedFields , ...this . _requestedRelations , ... this . _neededFields ] ;
71
76
const include = [
72
77
...new QueryBuilder ( ) . getIncludes ( this . _model , fields . length ? fields : null ) ,
73
78
...this . _customerIncludes ,
@@ -87,6 +92,11 @@ class QueryOptions {
87
92
return this . _order ;
88
93
}
89
94
95
+ get _hasRequestedSmartFields ( ) {
96
+ return this . _schema . fields
97
+ . some ( ( field ) => field . isVirtual && this . _requestedFields . has ( field . field ) ) ;
98
+ }
99
+
90
100
/**
91
101
* @param {sequelize.model } model Sequelize model that should be targeted
92
102
* @param {boolean } options.includeRelations Include BelongsTo and HasOne relations by default
@@ -102,8 +112,8 @@ class QueryOptions {
102
112
this . _options = options ;
103
113
104
114
// Used to compute relations that will go in the final 'include'
105
- this . _restrictFieldsOnRootModel = false ;
106
115
this . _requestedFields = new Set ( ) ;
116
+ this . _requestedRelations = new Set ( ) ;
107
117
this . _neededFields = new Set ( ) ;
108
118
this . _scopes = [ ] ; // @see sequelizeScopes getter
109
119
@@ -117,7 +127,7 @@ class QueryOptions {
117
127
if ( this . _options . includeRelations ) {
118
128
_ . values ( this . _model . associations )
119
129
. filter ( ( association ) => [ 'HasOne' , 'BelongsTo' ] . includes ( association . associationType ) )
120
- . forEach ( ( association ) => this . _requestedFields . add ( association . associationAccessor ) ) ;
130
+ . forEach ( ( association ) => this . _requestedRelations . add ( association . associationAccessor ) ) ;
121
131
}
122
132
}
123
133
@@ -128,12 +138,10 @@ class QueryOptions {
128
138
* @param {string[] } fields the output of the extractRequestedFields() util function
129
139
* @param {boolean } applyOnRootModel restrict fetched fields also on the root
130
140
*/
131
- async requireFields ( fields , applyOnRootModel = false ) {
141
+ async requireFields ( fields ) {
132
142
if ( fields ) {
133
143
fields . forEach ( ( field ) => this . _requestedFields . add ( field ) ) ;
134
144
}
135
-
136
- this . _restrictFieldsOnRootModel = Boolean ( applyOnRootModel ) ;
137
145
}
138
146
139
147
/**
0 commit comments