graphql-rails-generators 1.1.0 → 1.1.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38981ddd6d3252268196ca9c333672436e63ee24badf5fa54e72915c4bbcfeb5
4
- data.tar.gz: cbe8ba3110f66a30c2dbba7e2301b33e7ab52bd7deb2b6f7e4d37afc0b1bb9f0
3
+ metadata.gz: 5b3e945d1874ce80d7b6869974c0ff1ed879ab4c05a0cf7c95f45e92a7353592
4
+ data.tar.gz: 303b4b236b892bdf7062153bbd502f198426ca666557a2a3edee34964be8edb1
5
5
  SHA512:
6
- metadata.gz: e359081f8e02097e84af9d00fdc507e6d42fdc6d2b9727fb8732fc5f8b420da9d6279e62b99f79ab6f5b5bdf055484499a74df2cc9c4b9f829533afa1d046949
7
- data.tar.gz: d28b879ad5152567bd3e66b58dfe5713c3920f315553c5b94e0e8836f790914de8c1b5b5bd4886abd908f076712967e479eadc053bbd0d6f58738265f3446d57
6
+ metadata.gz: 00fc8c39ac7fc1fbe52c5441af7c23992767837e6416466cb10265ef756195c241f3736aa90b7d8079536f3d75e2efb5ae3b098114be99bf51fbe1c7ed39d03b
7
+ data.tar.gz: eb88f4cc1003f4eedfecead2bfb983f1a47aa8ee318a20fd17436cfb03b995073baf456adb7ad76d535f3b9f9205a4294e9ef0a5d1c06915c171f7b9f2c1672b
data/README.md CHANGED
@@ -2,11 +2,12 @@
2
2
 
3
3
  A few generators to make it easy to integrate your Rails models with [graphql-ruby](https://github.com/rmosolgo/graphql-ruby). I created this because I was wasting too many keystrokes copying my model schema by hand to create graphql types.
4
4
 
5
- This project contains three generators that look at your ActiveRecord model schema and generates graphql types for you.
5
+ This project contains generators that look at your ActiveRecord model schema and generates graphql types for you.
6
6
 
7
- * `gql:model_type Post` - Generate a graphql type for a model
8
- * `gql:input Post` - Generate a graphql input type for a model
9
- * `gql:mutation Update Post` - Generate a graphql mutation class for a model
7
+ - `gql:model_type Post` - Generate a graphql type for a model
8
+ - `gql:input Post` - Generate a graphql input type for a model
9
+ - `gql:mutation Update Post` - Generate a graphql mutation class for a model
10
+ - `gql:search_object` - A search object based on [SearchObjectGraphQL](https://github.com/RStankov/SearchObjectGraphQL)
10
11
 
11
12
  ## Installation
12
13
 
@@ -28,7 +29,11 @@ Generate a model type from a model.
28
29
  $ rails generate gql:model_type MODEL_CLASS
29
30
  ```
30
31
 
31
- Result:
32
+ #### Options
33
+
34
+ * `--name` - customize the file/class name, useful if you don't want the default Type suffix.
35
+
36
+ #### Example
32
37
 
33
38
  ```ruby
34
39
  # app/graphql/post_type.rb
@@ -51,7 +56,12 @@ Generate an input type from a model.
51
56
  rails generate gql:input Post
52
57
  ```
53
58
 
54
- Result:
59
+ #### Options
60
+
61
+ * `--name` - customize the file/class name, useful if you don't want the default Input suffix.
62
+
63
+ #### Example
64
+
55
65
  ```ruby
56
66
  # app/graphql/types/post_input.rb
57
67
  module Types
@@ -72,7 +82,8 @@ Generate create, update and delete mutations for a model.
72
82
  rails generate gql:mutations Post
73
83
  ```
74
84
 
75
- Result:
85
+ #### Example
86
+
76
87
  ```ruby
77
88
  # app/graphql/types/post_input.rb
78
89
  module Types
@@ -97,7 +108,8 @@ The mutation generator generates something akin to an "upsert" mutation. It take
97
108
  rails generate gql:mutation Update Post
98
109
  ```
99
110
 
100
- Result:
111
+ #### Example
112
+
101
113
  ```ruby
102
114
  # app/graphql/mutations/update_post.rb
103
115
  module Mutations
@@ -126,4 +138,66 @@ module Mutations
126
138
  end
127
139
  end
128
140
  end
129
- ```
141
+ ```
142
+
143
+ ### gql:search_object MODEL_NAME
144
+
145
+ Generate a search object from a model using [SearchObjectGraphQL](https://github.com/RStankov/SearchObjectGraphQL)
146
+
147
+ If you have not yet created a base search resolver:
148
+
149
+ `rails g gql:model_search_base`
150
+
151
+ \*_Adds `gem 'search_object_graphql'` to gemfile_
152
+
153
+ #### Example
154
+
155
+ ```ruby
156
+ # app/graphql/resolvers/base_search_resolver.rb
157
+ module Resolvers
158
+ class BaseSearchResolver < GraphQL::Schema::Resolver
159
+ require 'search_object'
160
+ require 'search_object/plugin/graphql'
161
+ include SearchObject.module(:graphql)
162
+ end
163
+ end
164
+ ```
165
+
166
+ Then generate a search object for your model:
167
+
168
+ `rails g gql:model_search Post`
169
+
170
+ #### Example
171
+
172
+ ```ruby
173
+ # app/graphql/resolvers/post_search.rb
174
+ module Resolvers
175
+ class PostSearch < Resolvers::BaseSearchResolver
176
+ type [Types::PostType], null: false
177
+ description "Lists posts"
178
+
179
+ scope { Post.all }
180
+
181
+ option(:id, type: Int) { |scope, value| scope.where id: value }
182
+ option(:title, type: String) { |scope, value| scope.where title: value }
183
+ option(:body, type: Int) { |scope, value| scope.where rating: value }
184
+ option(:created_at, type: GraphQL::Types::ISO8601DateTime) { |scope, value| scope.where created_at: value }
185
+ option(:updated_at, type: GraphQL::Types::ISO8601DateTime) { |scope, value| scope.where updated_at: value }
186
+
187
+ def resolve
188
+ []
189
+ end
190
+
191
+ end
192
+ end
193
+ ```
194
+
195
+ This will also insert a search field into the beginning of query_type.rb
196
+
197
+ ```ruby
198
+ #app/graphql/types/query_type.rb
199
+ module Types
200
+ class QueryType < Types::BaseObject
201
+ field :posts, resolver: Resolvers::PostSearch
202
+ ...
203
+ ```
@@ -2,40 +2,71 @@ require 'rails/generators/base'
2
2
 
3
3
  module Gql
4
4
  module GqlGeneratorBase
5
- extend ActiveSupport::Concern
5
+ protected
6
6
 
7
- included do
8
- protected
7
+ # Generate a namedspaced class name with the mutation prefix
8
+ def prefixed_class_name(prefix)
9
+ (class_path + ["#{prefix}_#{file_name}"]).map!(&:camelize).join("::")
10
+ end
9
11
 
10
- # Generate a namedspaced class name with the mutation prefix
11
- def prefixed_class_name(prefix)
12
- (class_path + ["#{prefix}_#{file_name}"]).map!(&:camelize).join("::")
13
- end
12
+ def type_map
13
+ {
14
+ integer: 'Int',
15
+ string: 'String',
16
+ boolean: 'Boolean',
17
+ decimal: 'Float',
18
+ datetime: 'GraphQL::Types::ISO8601DateTime',
19
+ date: 'GraphQL::Types::ISO8601Date',
20
+ hstore: 'GraphQL::Types::JSON',
21
+ text: 'String',
22
+ json: 'GraphQL::Types::JSON',
23
+ jsonb: 'GraphQL::Types::JSON'
24
+ }
25
+ end
14
26
 
15
- def type_map
16
- {
17
- integer: 'Int',
18
- string: 'String',
19
- boolean: 'Boolean',
20
- decimal: 'Float',
21
- datetime: 'GraphQL::Types::ISO8601DateTime',
22
- date: 'GraphQL::Types::ISO8601Date',
23
- hstore: 'GraphQL::Types::JSON',
24
- text: 'String',
25
- json: 'GraphQL::Types::JSON'
26
- }
27
- end
28
-
29
- def map_model_types(model_name)
30
- klass = model_name.constantize
31
- associations = klass.reflect_on_all_associations(:belongs_to)
32
- bt_columns = associations.map(&:foreign_key)
33
-
34
- klass.columns
35
- .reject { |col| bt_columns.include?(col.name) }
36
- .reject { |col| type_map[col.type].nil? }
37
- .map { |col| {name: col.name, gql_type: type_map[col.type]} }
27
+ def map_model_types(model_name)
28
+ klass = model_name.constantize
29
+ associations = klass.reflect_on_all_associations(:belongs_to)
30
+ bt_columns = associations.map(&:foreign_key)
31
+
32
+ klass.columns
33
+ .reject { |col| bt_columns.include?(col.name) }
34
+ .reject { |col| type_map[col.type].nil? }
35
+ .map do |col|
36
+ {
37
+ name: col.name,
38
+ null: col.null,
39
+ gql_type: klass.primary_key == col.name ? 'GraphQL::Types::ID' : type_map[col.type]
40
+ }
41
+ end
42
+ end
43
+
44
+ def root_directory(namespace)
45
+ "app/graphql/#{namespace.underscore}"
46
+ end
47
+
48
+ def wrap_in_namespace(namespace)
49
+ namespace = namespace.split('::')
50
+ namespace.shift if namespace[0].empty?
51
+
52
+ code = namespace.each_with_index.map { |name, i| " " * i + "module #{name}" }.join("\n")
53
+ code << "\n" << yield(namespace.size) << "\n"
54
+ code << (namespace.size - 1).downto(0).map { |i| " " * i + "end" }.join("\n")
55
+ code
56
+ end
57
+
58
+ def class_with_fields(namespace, name, superclass, fields)
59
+ wrap_in_namespace(namespace) do |indent|
60
+ klass = []
61
+ klass << sprintf("%sclass %s < %s", " " * indent, name, superclass)
62
+
63
+ fields.each do |field|
64
+ klass << sprintf("%sfield :%s, %s, null: %s", " " * (indent + 1), field[:name], field[:gql_type], field[:null])
65
+ end
66
+
67
+ klass << sprintf("%send", " " * indent)
68
+ klass.join("\n")
38
69
  end
39
70
  end
40
71
  end
41
- end
72
+ end
@@ -3,15 +3,29 @@ module Gql
3
3
  class InputGenerator < Rails::Generators::Base
4
4
  include GqlGeneratorBase
5
5
  source_root File.expand_path('../templates', __FILE__)
6
+
6
7
  argument :model_name, type: :string
7
-
8
+
9
+ class_option :name, type: :string
10
+ class_option :include_columns, type: :array, default: []
11
+ class_option :superclass, type: :string, default: 'Types::BaseInputObject'
12
+ class_option :namespace, type: :string, default: 'Types::Input'
13
+
8
14
  def generate_input_type
9
- file_name = model_name
15
+ name = options['name'].nil? ? "#{model_name}Input" : options['name']
16
+ superclass = options['superclass']
10
17
 
11
18
  ignore = ['id', 'created_at', 'updated_at']
12
- @fields = map_model_types(model_name).reject { |field| ignore.include?(field[:name]) }
19
+ fields = map_model_types(model_name)
20
+ fields.reject! { |field| ignore.include?(field[:name]) }
21
+ if options['include_columns'].any?
22
+ fields.reject! { |field| !options['include_columns'].include?(field[:name]) }
23
+ end
24
+
25
+ code = class_with_fields(options['namespace'], name, superclass, fields)
26
+ file_name = File.join(root_directory(options['namespace']), "#{name.underscore}.rb")
13
27
 
14
- template('input_type.rb', "app/graphql/types/input/#{file_name.underscore}_input.rb")
28
+ create_file file_name, code
15
29
  end
16
30
  end
17
- end
31
+ end
@@ -0,0 +1,9 @@
1
+ module Gql
2
+ class ModelSearchBaseGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../templates', __FILE__)
4
+ def generate_model_search_base
5
+ gem 'search_object_graphql'
6
+ template('model_search_base.rb', "app/graphql/resolvers/base_search_resolver.rb")
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,19 @@
1
+ require_relative 'gql_generator_base'
2
+ module Gql
3
+ class ModelSearchGenerator < Rails::Generators::Base
4
+ include GqlGeneratorBase
5
+ source_root File.expand_path('../templates', __FILE__)
6
+ argument :model_name, type: :string
7
+
8
+ def search
9
+ inject_into_file(
10
+ "app/graphql/types/query_type.rb",
11
+ "\t\tfield :#{model_name.downcase.pluralize}, resolver: Resolvers::#{model_name}Search \n",
12
+ :after => "class QueryType < Types::BaseObject\n"
13
+ )
14
+ file_name = "#{model_name.underscore}_search"
15
+ @fields = map_model_types(model_name)
16
+ template('model_search.rb', "app/graphql/resolvers/#{file_name}.rb")
17
+ end
18
+ end
19
+ end
@@ -3,12 +3,28 @@ module Gql
3
3
  class ModelTypeGenerator < Rails::Generators::Base
4
4
  include GqlGeneratorBase
5
5
  source_root File.expand_path('../templates', __FILE__)
6
+
6
7
  argument :model_name, type: :string
7
8
 
9
+ class_option :name, type: :string
10
+ class_option :include_columns, type: :array, default: []
11
+ class_option :superclass, type: :string, default: 'Types::BaseObject'
12
+ class_option :namespace, type: :string, default: 'Types'
13
+
8
14
  def type
9
- file_name = "#{model_name.underscore}_type"
10
- @fields = map_model_types(model_name)
11
- template('model_type.rb', "app/graphql/types/#{file_name}.rb")
15
+ name = options['name'].nil? ? "#{model_name}Type" : options['name']
16
+
17
+ superclass = options['superclass']
18
+
19
+ fields = map_model_types(model_name)
20
+ if options['include_columns'].any?
21
+ fields.reject! { |field| !options['include_columns'].include?(field[:name]) }
22
+ end
23
+
24
+ code = class_with_fields(options['namespace'], name, superclass, fields)
25
+ file_name = File.join(root_directory(options['namespace']), "#{name.underscore}.rb")
26
+
27
+ create_file file_name, code
12
28
  end
13
29
  end
14
- end
30
+ end
@@ -0,0 +1,16 @@
1
+ module Resolvers
2
+ class <%= @resolver_prefix %><%= @model_name %>Search < Resolvers::BaseSearchResolver
3
+ type [Types::<%= @model_name %>Type], null: false
4
+ description "Lists <%= @model_name.downcase.pluralize %>"
5
+
6
+ scope { <%= @model_name %>.all }
7
+
8
+ <% @fields.each do |field| -%>
9
+ option(:<%= field[:name] %>, type: <%= field[:gql_type] %>) { |scope, value| scope.where <%= field[:name] %>: value }
10
+ <% end %>
11
+ def resolve
12
+ []
13
+ end
14
+
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Resolvers
2
+ class BaseSearchResolver < GraphQL::Schema::Resolver
3
+ require 'search_object'
4
+ require 'search_object/plugin/graphql'
5
+ include SearchObject.module(:graphql)
6
+ end
7
+ end
@@ -1,3 +1,3 @@
1
1
  module GraphqlRailsGenerators
2
- VERSION = '1.1.0'
2
+ VERSION = '1.1.1'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql-rails-generators
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Sharp
@@ -20,14 +20,16 @@ files:
20
20
  - README.md
21
21
  - lib/generators/gql/gql_generator_base.rb
22
22
  - lib/generators/gql/input_generator.rb
23
+ - lib/generators/gql/model_search_base_generator.rb
24
+ - lib/generators/gql/model_search_generator.rb
23
25
  - lib/generators/gql/model_type_generator.rb
24
26
  - lib/generators/gql/mutation_generator.rb
25
27
  - lib/generators/gql/mutations_generator.rb
26
28
  - lib/generators/gql/templates/create_mutation.rb
27
29
  - lib/generators/gql/templates/delete_mutation.rb
28
- - lib/generators/gql/templates/input_type.rb
29
30
  - lib/generators/gql/templates/model_mutation.rb
30
- - lib/generators/gql/templates/model_type.rb
31
+ - lib/generators/gql/templates/model_search.rb
32
+ - lib/generators/gql/templates/model_search_base.rb
31
33
  - lib/generators/gql/templates/update_mutation.rb
32
34
  - lib/graphql-rails-generators/version.rb
33
35
  homepage: https://github.com/ajsharp/graphql-rails-generators
@@ -1,9 +0,0 @@
1
- module Types
2
- module Input
3
- class <%= @model_name %>Input < Types::BaseInputObject
4
- <% @fields.each do |field| -%>
5
- argument :<%= field[:name] %>, <%= field[:gql_type] %>, required: false
6
- <% end %>
7
- end
8
- end
9
- end
@@ -1,7 +0,0 @@
1
- module Types
2
- class <%= @model_name %>Type < Types::BaseObject
3
- <% @fields.each do |field| -%>
4
- field :<%= field[:name] %>, <%= field[:gql_type] %>, null: true
5
- <% end %>
6
- end
7
- end