graphql_model_mapper 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+