graphql_model_mapper 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,340 @@
1
+ module GraphqlModelMapper
2
+ module MapperType
3
+ def self.graphql_types(
4
+ name: self.name,
5
+ query: {},
6
+ update: {},
7
+ delete: {},
8
+ create: {}
9
+ )
10
+ typesuffix = method(__method__).parameters.map { |arg| eval arg[1].to_s }.hash.abs.to_i.to_s
11
+ return GraphqlModelMapper.get_constant("#{name.upcase}#{typesuffix}_GRAPHQL_DEFAULT_TYPES") if GraphqlModelMapper.const_defined?("#{name.upcase}#{typesuffix}_GRAPHQL_DEFAULT_TYPES")
12
+
13
+ graphql_type = {}
14
+ graphql_type[:query] = query
15
+ graphql_type[:update] = update
16
+ graphql_type[:delete] = delete
17
+ graphql_type[:create] = create
18
+ merged_graphql_type = self.graphql_default_types.deep_merge(graphql_type)
19
+ GraphqlModelMapper.set_constant("#{name.upcase}#{typesuffix}_GRAPHQL_DEFAULT_TYPES", merged_graphql_type)
20
+
21
+ merged_graphql_type
22
+ end
23
+
24
+
25
+ def self.get_ar_object_with_params(name, type_key: nil, type_sub_key: nil)
26
+ self.get_ar_object(name, self.get_type_params(name, type_key: type_key, type_sub_key: type_sub_key))
27
+ end
28
+
29
+ def self.get_ar_object(name,
30
+ required_attributes: [],
31
+ excluded_attributes: [],
32
+ allowed_attributes: [],
33
+ foreign_keys: false,
34
+ primary_keys: false,
35
+ validation_keys: false,
36
+ association_macro: nil,
37
+ source_nulls: true,
38
+ type_key: nil,
39
+ type_sub_key: nil)
40
+
41
+
42
+ #typesuffix = method(__method__).parameters.map { |arg| eval arg[1].to_s }.hash.abs.to_i.to_s
43
+ typesuffix = "#{type_key.to_s.classify}#{GraphqlModelMapper.underscore(type_sub_key.to_s)}".camelize
44
+ typename = "#{GraphqlModelMapper.get_type_name(name)}#{typesuffix}"
45
+
46
+ return GraphqlModelMapper.get_constant(typename) if GraphqlModelMapper.defined_constant?(typename)
47
+
48
+ model = name.classify.constantize
49
+
50
+ required_attributes = required_attributes.map(&:to_sym) | (validation_keys ? self.model_validation_keys(name) : [])
51
+
52
+ columns = model.columns_hash
53
+
54
+ # figure out which association fields we are exposing
55
+ association_includes = (model.reflect_on_all_associations(association_macro).map(&:name)).map(&:to_sym) - excluded_attributes
56
+
57
+ # find all relations for this model, skip ones where the association klass is invalid, as well as polymorphic associations, be cognizant of include/exclude arrays similar to dbfields
58
+ associations = model.reflect_on_all_associations(association_macro).select{|t| begin t.klass rescue next end}.select{|t| !t.options[:polymorphic] && association_includes.include?(t.name.to_sym) }
59
+ # never show foreign keys for defined associations
60
+ db_fields_never = foreign_keys ? [] : ( associations.map(&:association_foreign_key) + associations.map(&:options).select{|v| v.key?(:foreign_key) }.map {|x| x[:foreign_key]} ).uniq.map(&:to_sym)
61
+
62
+ # figure out which database fields we are exposing
63
+ allowed_attributes = allowed_attributes.count > 0 ? allowed_attributes.map(&:to_sym) : associations.map(&:name) + columns.keys.map(&:to_sym)
64
+ allowed_associations = (associations.map(&:name) - excluded_attributes - db_fields_never) & allowed_attributes
65
+ db_fields = (columns.keys.map(&:to_sym) - excluded_attributes - db_fields_never) & allowed_attributes
66
+ associations = associations.select{|m| allowed_associations.include?(m.name)}
67
+
68
+ ret_type = GraphQL::InputObjectType.define do
69
+ #ensure type name is unique so it does not collide with known types
70
+ name typename
71
+ description "an input interface for the #{name} ActiveRecord model"
72
+ # create GraphQL fields for each exposed database field
73
+ db_fields.select{|s| (primary_keys && s.to_sym == :id)}.each do |f|
74
+ argument f.to_sym, -> {GraphqlModelMapper::MapperType.convert_type(columns[f.to_s].type, columns[f.to_s].sql_type, (source_nulls ? columns[f.to_s].null : true))}
75
+ end
76
+ db_fields.select{|s| required_attributes.include?(s)}.each do |f|
77
+ argument f.to_sym, -> {GraphqlModelMapper.convert_type(columns[f.to_s].type, columns[f.to_s].sql_type, false)}
78
+ end
79
+ # create GraphQL fields for each association
80
+ associations.sort_by(&:name).each do |reflection|
81
+ begin
82
+ klass = reflection.klass
83
+ rescue
84
+ next # most likely an invalid association without a class name, skip if other errors are encountered
85
+ end
86
+ if reflection.macro == :has_many
87
+ argument reflection.name.to_sym, -> {GraphqlModelMapper::MapperType.get_ar_object_with_params(klass.name, type_key: type_key, type_sub_key: type_sub_key).to_list_type} do
88
+ if GraphqlModelMapper.use_authorize
89
+ authorized ->(ctx, model_name, access_type) { GraphqlModelMapper.authorized?(ctx, model_name, access_type.to_sym) }
90
+ model_name klass.name
91
+ access_type type_key.to_s
92
+ end
93
+ end
94
+ else
95
+ argument reflection.name.to_sym, -> {GraphqlModelMapper::MapperType.get_ar_object_with_params(klass.name, type_key: type_key, type_sub_key: type_sub_key)} do
96
+ if GraphqlModelMapper.use_authorize
97
+ authorized ->(ctx, model_name, access_type) { GraphqlModelMapper.authorized?(ctx, model_name, access_type.to_sym) }
98
+ model_name klass.name
99
+ access_type type_key.to_s
100
+ end
101
+ end
102
+ end
103
+ end
104
+
105
+ db_fields.reject{|s| (primary_keys && s.to_sym == :id) || required_attributes.include?(s)}.sort.each do |f|
106
+ argument f.to_sym, -> {GraphqlModelMapper::MapperType.convert_type(columns[f.to_s].type, columns[f.to_s].sql_type, (source_nulls ? columns[f.to_s].null : true))}
107
+ end
108
+ end if type_sub_key == :input_type
109
+
110
+ ret_type = GraphQL::ObjectType.define do
111
+ #ensure type name is unique so it does not collide with known types
112
+ name typename
113
+ description "an output interface for the #{name} ActiveRecord model"
114
+ # create GraphQL fields for each exposed database field
115
+ db_fields.select{|s| (primary_keys && s.to_sym == :id)}.each do |f|
116
+ #puts "source null #{f} #{source_nulls ? columns[f.to_s].null : true}"
117
+ field f.to_sym, -> {GraphqlModelMapper::MapperType.convert_type(columns[f.to_s].type, columns[f.to_s].sql_type, (source_nulls ? columns[f.to_s].null : true))}
118
+ end
119
+ db_fields.select{|s| required_attributes.include?(s)}.sort.each do |f|
120
+ field f.to_sym, -> {GraphqlModelMapper::MapperType.convert_type(columns[f.to_s].type, columns[f.to_s].sql_type, false)}
121
+ end
122
+ # create GraphQL fields for each association
123
+ associations.sort_by(&:name).each do |reflection|
124
+ begin
125
+ klass = reflection.klass
126
+ rescue
127
+ next # most likely an invalid association without a class name, skip if other errors are encountered
128
+ end
129
+ if reflection.macro == :has_many
130
+ if [:deep].include?(GraphqlModelMapper.nesting_strategy) && type_key == :query
131
+ connection reflection.name.to_sym, -> {GraphqlModelMapper::MapperType.get_ar_object_with_params(klass.name, type_key: type_key, type_sub_key: type_sub_key).connection_type} do
132
+ if GraphqlModelMapper.use_authorize
133
+ authorized ->(ctx, model_name, access_type) { GraphqlModelMapper.authorized?(ctx, model_name, access_type.to_sym) }
134
+ model_name klass.name
135
+ access_type :read.to_s
136
+ end
137
+ end
138
+ else
139
+ field reflection.name.to_sym, -> {GraphqlModelMapper::MapperType.get_ar_object_with_params(klass.name, type_key: type_key, type_sub_key: type_sub_key).to_list_type} do
140
+ if GraphqlModelMapper.use_authorize
141
+ authorized ->(ctx, model_name, access_type) { GraphqlModelMapper.authorized?(ctx, model_name, access_type.to_sym) }
142
+ model_name klass.name
143
+ access_type :read.to_s
144
+ end
145
+ end
146
+ end
147
+ else
148
+ field reflection.name.to_sym, -> {GraphqlModelMapper::MapperType.get_ar_object_with_params(klass.name, type_key: type_key, type_sub_key: type_sub_key)} do
149
+ if GraphqlModelMapper.use_authorize
150
+ authorized ->(ctx, model_name, access_type) { GraphqlModelMapper.authorized?(ctx, model_name, access_type.to_sym) }
151
+ model_name klass.name
152
+ access_type :read.to_s
153
+ end
154
+ end
155
+ end
156
+ end
157
+ db_fields.reject{|s| (primary_keys && s.to_sym == :id) || required_attributes.include?(s)}.sort.each do |f|
158
+ #puts "source null #{f} #{source_nulls ? columns[f.to_s].null : true}"
159
+ field f.to_sym, -> {GraphqlModelMapper::MapperType.convert_type(columns[f.to_s].type, columns[f.to_s].sql_type, (source_nulls ? columns[f.to_s].null : true))}
160
+ end
161
+ end if type_sub_key == :output_type
162
+ GraphqlModelMapper.set_constant(typename, ret_type) if !GraphqlModelMapper.defined_constant?(typename)
163
+ ret_type
164
+ end
165
+
166
+ def self.get_type_params(name, type_key: nil, type_sub_key: nil)
167
+ model = name.classify.constantize
168
+ if model.public_methods.include?(:graphql_types)
169
+ params = model.graphql_types
170
+ else
171
+ params = self.graphql_default_types
172
+ end
173
+ #puts params
174
+ if !type_key.nil?
175
+ if params.keys.include?(type_key.to_sym)
176
+ params = params[type_key.to_sym]
177
+ if !type_sub_key.nil?
178
+ if params.keys.include?(type_sub_key.to_sym)
179
+ params = params[type_sub_key.to_sym]
180
+ else
181
+ params = nil
182
+ end
183
+ end
184
+ else
185
+ params = nil
186
+ end
187
+ end
188
+ params
189
+ end
190
+
191
+ def self.graphql_default_types(
192
+ query: {
193
+ input_type: {
194
+ required_attributes: [],
195
+ excluded_attributes: [],
196
+ allowed_attributes: [],
197
+ foreign_keys: true,
198
+ primary_keys: true,
199
+ validation_keys: false,
200
+ association_macro: nil,
201
+ source_nulls: false,
202
+ type_key: :query,
203
+ type_sub_key: :input_type
204
+ },
205
+ output_type: {
206
+ required_attributes: [],
207
+ excluded_attributes: [],
208
+ allowed_attributes: [],
209
+ foreign_keys: true,
210
+ primary_keys: true,
211
+ validation_keys: false,
212
+ association_macro: nil,
213
+ source_nulls: false,
214
+ type_key: :query,
215
+ type_sub_key: :output_type
216
+ }
217
+ },
218
+ update: {
219
+ input_type: {
220
+ required_attributes: [],
221
+ excluded_attributes: [],
222
+ allowed_attributes: [],
223
+ foreign_keys: true,
224
+ primary_keys: true,
225
+ validation_keys: false,
226
+ association_macro: nil,
227
+ source_nulls: false,
228
+ type_key: :update,
229
+ type_sub_key: :input_type
230
+ },
231
+ output_type: {
232
+ required_attributes: [],
233
+ excluded_attributes: [],
234
+ allowed_attributes: [],
235
+ foreign_keys: true,
236
+ primary_keys: true,
237
+ validation_keys: false,
238
+ association_macro: nil,
239
+ source_nulls: true,
240
+ type_key: :update,
241
+ type_sub_key: :output_type
242
+ }
243
+ },
244
+ delete: {
245
+ input_type: {
246
+ required_attributes: [:id],
247
+ excluded_attributes: [],
248
+ allowed_attributes: [:id],
249
+ foreign_keys: false,
250
+ primary_keys: true,
251
+ validation_keys: false,
252
+ association_macro: nil,
253
+ source_nulls: false,
254
+ type_key: :delete,
255
+ type_sub_key: :input_type
256
+ },
257
+ output_type: {
258
+ required_attributes: [],
259
+ excluded_attributes: [],
260
+ allowed_attributes: [],
261
+ foreign_keys: false,
262
+ primary_keys: true,
263
+ validation_keys: false,
264
+ association_macro: nil,
265
+ source_nulls: true,
266
+ type_key: :delete,
267
+ type_sub_key: :output_type
268
+ }
269
+ },
270
+ create: {
271
+ input_type: {
272
+ required_attributes: [],
273
+ excluded_attributes: [],
274
+ allowed_attributes: [],
275
+ foreign_keys: true,
276
+ primary_keys: false,
277
+ validation_keys: false,
278
+ association_macro: :has_many,
279
+ source_nulls: false,
280
+ type_key: :create,
281
+ type_sub_key: :input_type
282
+ },
283
+ output_type: {
284
+ required_attributes: [],
285
+ excluded_attributes: [],
286
+ allowed_attributes: [],
287
+ foreign_keys: true,
288
+ primary_keys: true,
289
+ validation_keys: false,
290
+ association_macro: nil,
291
+ source_nulls: true,
292
+ type_key: :create,
293
+ type_sub_key: :output_type
294
+ }
295
+ })
296
+ return GraphqlModelMapper.get_constant("GRAPHQL_DEFAULT_TYPES") if GraphqlModelMapper.const_defined?("GRAPHQL_DEFAULT_TYPES")
297
+
298
+ graphql_type = {}
299
+ graphql_type[:query] = query
300
+ graphql_type[:update] = update
301
+ graphql_type[:delete] = delete
302
+ graphql_type[:create] = create
303
+
304
+ GraphqlModelMapper.set_constant("GRAPHQL_DEFAULT_TYPES", graphql_type)
305
+ graphql_type
306
+ end
307
+
308
+ def self.model_validation_keys(name)
309
+ model = name.classify.constantize
310
+ validation_attributes = model.validators.select{|m| m.is_a?(ActiveModel::Validations::PresenceValidator) && !m.options[:if]}.map(&:attributes).flatten
311
+ model.reflect_on_all_associations.select{|p| validation_attributes.include?(p.name) }.map(&:foreign_key).map(&:to_sym) | validation_attributes & model.columns_hash.keys.map(&:to_sym)
312
+ end
313
+
314
+ # convert a database type to a GraphQL type
315
+ # @param db_type [Symbol] the type returned by columns_hash[column_name].type
316
+ # @param db_sql_type [String] the sql_type returned by columns_hash[column_name].sql_type
317
+ # @return [GraphQL::ScalarType] a GraphQL type
318
+ def self.convert_type db_type, db_sql_type="", nullable=true
319
+ # because we are outside of a GraphQL define block we cannot use the types helper
320
+ # we must refer directly to the built-in GraphQL scalar types
321
+ case db_type
322
+ when :integer
323
+ nullable ? GraphQL::INT_TYPE : !GraphQL::INT_TYPE
324
+ when :decimal, :float
325
+ nullable ? GraphQL::FLOAT_TYPE : !GraphQL::FLOAT_TYPE
326
+ when :boolean
327
+ nullable ? GraphQL::BOOLEAN_TYPE : !GraphQL::BOOLEAN_TYPE
328
+ when :date, :datetime
329
+ nullable ? GraphqlModelMapper::DATE_TYPE : !GraphqlModelMapper::DATE_TYPE
330
+ else
331
+ case db_sql_type.to_sym #these are strings not symbols
332
+ when :geometry, :multipolygon, :polygon
333
+ nullable ? GraphqlModelMapper::GEOMETRY_TYPE : !GraphqlModelMapper::GEOMETRY_TYPE
334
+ else
335
+ nullable ? GraphQL::STRING_TYPE : !GraphQL::STRING_TYPE
336
+ end
337
+ end
338
+ end
339
+ end
340
+ end
@@ -0,0 +1,125 @@
1
+ module GraphqlModelMapper
2
+ module Mutation
3
+ def self.graphql_update(name: "",description:"",
4
+ resolver: nil)
5
+
6
+
7
+ input_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :update, type_sub_key: :input_type)
8
+ output_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :update, type_sub_key: :output_type)
9
+
10
+ self.get_mutation(name, description, "Update", resolver, input_type, output_type, name.downcase, "item")
11
+ end
12
+
13
+ def self.graphql_delete(name: "", description:"",
14
+ resolver: nil,
15
+ arguments: [],
16
+ scope_methods: [])
17
+
18
+ input_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :delete, type_sub_key: :input_type)
19
+ output_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :delete, type_sub_key: :output_type).to_list_type
20
+ self.get_delete_mutation(name, description, "Delete", resolver, arguments, scope_methods, input_type, output_type)
21
+ end
22
+
23
+ def self.graphql_create(name: "", description:"",
24
+ resolver: nil)
25
+
26
+ input_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :create, type_sub_key: :input_type)
27
+ output_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :create, type_sub_key: :output_type)
28
+
29
+ self.get_mutation(name, description, "Create", resolver, input_type, output_type, name.downcase, "item")
30
+ end
31
+
32
+ def self.get_mutation(name, description, operation_name, resolver, input_type, output_type, input_name, output_name)
33
+ mutation_type_name = GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(name)}#{operation_name}")
34
+ return GraphqlModelMapper.get_constant(mutation_type_name) if GraphqlModelMapper.defined_constant?(mutation_type_name)
35
+ mutation_type = GraphQL::Relay::Mutation.define do
36
+ name mutation_type_name
37
+ description description
38
+ input_field input_name.to_sym, -> {input_type}
39
+ return_field output_name.to_sym, -> {output_type}
40
+
41
+ resolve resolver
42
+ end
43
+
44
+ GraphqlModelMapper.set_constant(mutation_type_name, mutation_type.field)
45
+ GraphqlModelMapper.get_constant(mutation_type_name)
46
+ end
47
+
48
+ def self.get_delete_mutation(name, description, operation_name, resolver, arguments, scope_methods, input_type, output_type)
49
+ query_type_name = GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(name)}#{operation_name}")
50
+ return GraphqlModelMapper.get_constant(query_type_name) if GraphqlModelMapper.defined_constant?(query_type_name)
51
+
52
+ model = name.classify.constantize
53
+
54
+ default_arguments = self.get_default_select_arguments(model, scope_methods)
55
+ select_input_type_name = GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(name)}SelectInput")
56
+ if GraphqlModelMapper.defined_constant?(select_input_type_name)
57
+ query_input_object_type = GraphqlModelMapper.get_constant(select_input_type_name)
58
+ else
59
+ query_input_object_type = GraphQL::InputObjectType.define do
60
+ name select_input_type_name
61
+ default_arguments.each do |k|
62
+ argument k[:name].to_sym, k[:type], k[:description], default_value: k[:default]
63
+ end
64
+ end
65
+ GraphqlModelMapper.set_constant(select_input_type_name, query_input_object_type)
66
+ end
67
+
68
+
69
+ ret_type = GraphQL::Relay::Mutation.define do
70
+ name query_type_name
71
+ #return_field :item, output_object_type
72
+ return_field :items, output_type
73
+ return_field :total, -> {GraphQL::INT_TYPE}
74
+
75
+ #description description
76
+ #input_field "input".to_sym, -> {input_object_type}
77
+ input_field :select, -> {!query_input_object_type}
78
+
79
+ resolve resolver
80
+ end
81
+ GraphqlModelMapper.set_constant(query_type_name, ret_type.field)
82
+ GraphqlModelMapper.get_constant(query_type_name)
83
+ end
84
+
85
+ def self.get_default_select_arguments(model, scope_methods)
86
+ default_arguments = [
87
+ {:name=>:explain, :type=>GraphQL::BOOLEAN_TYPE, :default=>nil},
88
+ {:name=>:id, :type=>GraphQL::INT_TYPE, :default=>nil},
89
+ {:name=>:ids, :type=>GraphQL::INT_TYPE.to_list_type, :default=>nil},
90
+ {:name=>:limit, :type=>GraphQL::INT_TYPE, :default=>50},
91
+ {:name=>:offset, :type=>GraphQL::INT_TYPE, :default=>nil},
92
+ {:name=>:order, :type=>GraphQL::STRING_TYPE, :default=>nil},
93
+ {:name=>:where, :type=>GraphQL::STRING_TYPE.to_list_type, :default=>nil}
94
+ ]
95
+
96
+ scope_methods = scope_methods.map(&:to_sym)
97
+ #.select{|m| model.method(m.to_sym).arity == 0}
98
+ if (model.public_methods - model.instance_methods - Object.methods - ActiveRecord::Base.methods).include?(:with_deleted)
99
+ default_arguments << {:name=>:with_deleted, :type=>GraphQL::BOOLEAN_TYPE, :default=>false}
100
+ end
101
+ allowed_scope_methods = []
102
+ if scope_methods.count > 0
103
+ scope_methods.each do |s|
104
+ #.select{|m| model.method(m.to_sym).arity == 0}
105
+ allowed_scope_methods << s if (model.public_methods - model.instance_methods - Object.methods - ActiveRecord::Base.methods).include?(s)
106
+ end
107
+ if allowed_scope_methods.count > 0
108
+ typename = GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(model.name)}Scope_Enum")
109
+ if !GraphqlModelMapper.defined_constant?(typename)
110
+ enum_type = GraphQL::EnumType.define do
111
+ name typename
112
+ description "scope enum for #{GraphqlModelMapper.get_type_name(model.name)}"
113
+ allowed_scope_methods.sort.each do |s|
114
+ value(s, "")
115
+ end
116
+ end
117
+ GraphqlModelMapper.set_constant typename, enum_type
118
+ end
119
+ default_arguments << {:name=>:scope, :type=>GraphqlModelMapper.get_constant(typename), :default=>nil}
120
+ end
121
+ end
122
+ default_arguments
123
+ end
124
+ end
125
+ end
@@ -0,0 +1,107 @@
1
+ module GraphqlModelMapper
2
+ module Query
3
+ def self.graphql_query(name: "",
4
+ description: "",
5
+ resolver: nil,
6
+ arguments: [],
7
+ scope_methods: []
8
+ )
9
+
10
+ input_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :query, type_sub_key: :input_type)
11
+ output_type = GraphqlModelMapper::MapperType.get_ar_object_with_params(name, type_key: :query, type_sub_key: :output_type)
12
+ self.get_query(name, description, "Query", resolver, arguments, scope_methods, input_type, output_type)
13
+ end
14
+
15
+ def self.get_default_select_arguments(model, scope_methods)
16
+ default_arguments = [
17
+ {:name=>:explain, :type=>GraphQL::BOOLEAN_TYPE, :default=>nil},
18
+ {:name=>:id, :type=>GraphQL::INT_TYPE, :default=>nil},
19
+ {:name=>:ids, :type=>GraphQL::INT_TYPE.to_list_type, :default=>nil},
20
+ {:name=>:limit, :type=>GraphQL::INT_TYPE, :default=>50},
21
+ {:name=>:offset, :type=>GraphQL::INT_TYPE, :default=>nil},
22
+ {:name=>:order, :type=>GraphQL::STRING_TYPE, :default=>nil},
23
+ {:name=>:where, :type=>GraphQL::STRING_TYPE.to_list_type, :default=>nil}
24
+ ]
25
+
26
+ scope_methods = scope_methods.map(&:to_sym)
27
+ #.select{|m| model.method(m.to_sym).arity == 0}
28
+ if (model.public_methods - model.instance_methods - Object.methods - ActiveRecord::Base.methods).include?(:with_deleted)
29
+ default_arguments << {:name=>:with_deleted, :type=>GraphQL::BOOLEAN_TYPE, :default=>false}
30
+ end
31
+ allowed_scope_methods = []
32
+ if scope_methods.count > 0
33
+ scope_methods.each do |s|
34
+ #.select{|m| model.method(m.to_sym).arity == 0}
35
+ allowed_scope_methods << s if (model.public_methods - model.instance_methods - Object.methods - ActiveRecord::Base.methods).include?(s)
36
+ end
37
+ if allowed_scope_methods.count > 0
38
+ typename = GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(model.name)}Scope_Enum")
39
+ if !GraphqlModelMapper.defined_constant?(typename)
40
+ enum_type = GraphQL::EnumType.define do
41
+ name typename
42
+ description "scope enum for #{GraphqlModelMapper.get_type_name(model.name)}"
43
+ allowed_scope_methods.sort.each do |s|
44
+ value(s, "")
45
+ end
46
+ end
47
+ GraphqlModelMapper.set_constant typename, enum_type
48
+ end
49
+ default_arguments << {:name=>:scope, :type=>GraphqlModelMapper.get_constant(typename), :default=>nil}
50
+ end
51
+ end
52
+ default_arguments
53
+ end
54
+
55
+ def self.get_query(name, description, operation_name, resolver, arguments, scope_methods, input_type, output_type)
56
+
57
+ query_type_name = GraphqlModelMapper.get_type_case("#{GraphqlModelMapper.get_type_name(name)}#{operation_name}")
58
+ return GraphqlModelMapper.get_constant(query_type_name) if GraphqlModelMapper.defined_constant?(query_type_name)
59
+
60
+ model = name.classify.constantize
61
+
62
+ default_arguments = self.get_default_select_arguments(model, scope_methods)
63
+ select_input_type_name = "#{GraphqlModelMapper.get_type_case(GraphqlModelMapper.get_type_name(name))}QueryInput"
64
+ if GraphqlModelMapper.defined_constant?(select_input_type_name)
65
+ select_input_type = GraphqlModelMapper.get_constant(select_input_type_name)
66
+ else
67
+ select_input_type = GraphQL::InputObjectType.define do
68
+ name select_input_type_name
69
+ default_arguments.each do |k|
70
+ argument k[:name].to_sym, k[:type], k[:description], default_value: k[:default]
71
+ end
72
+ end
73
+ GraphqlModelMapper.set_constant(select_input_type_name, select_input_type)
74
+ end
75
+
76
+ total_output_type_name = "#{GraphqlModelMapper.get_type_name(name)}QueryPayload"
77
+ if GraphqlModelMapper.defined_constant?(total_output_type_name)
78
+ total_output_type = GraphqlModelMapper.get_constant(total_output_type_name)
79
+ else
80
+ total_output_type = GraphQL::ObjectType.define do
81
+ name total_output_type_name
82
+ if [:deep, :shallow].include?(GraphqlModelMapper.nesting_strategy)
83
+ connection :items, -> {output_type.connection_type}, hash_key: :items
84
+ else
85
+ field :items, -> {output_type.to_list_type}, hash_key: :items
86
+ end
87
+ field :total, -> {GraphQL::INT_TYPE}, hash_key: :total
88
+ end
89
+ GraphqlModelMapper.set_constant(total_output_type_name, total_output_type)
90
+ end
91
+
92
+
93
+ ret_type = GraphQL::Field.define do
94
+ name query_type_name
95
+ type total_output_type
96
+ #argument :select, -> {!select_input_type}
97
+ default_arguments.each do |k|
98
+ argument k[:name].to_sym, k[:type], k[:description], default_value: k[:default]
99
+ end
100
+
101
+ resolve resolver
102
+ end
103
+ GraphqlModelMapper.set_constant(query_type_name, ret_type)
104
+ GraphqlModelMapper.get_constant(query_type_name)
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,8 @@
1
+ module GraphqlModelMapper
2
+ class Railtie < Rails::Railtie
3
+ initializer 'Rails logger' do
4
+ GraphqlModelMapper.logger = Rails.logger
5
+ end
6
+ end
7
+ end
8
+