graphql_rails 0.6.0 → 0.7.0

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: cfcbe2a73989218dd084672e7402c553db62d23825096ba28f8a8af615c8ec63
4
- data.tar.gz: dee48916b9b0ee8c4205c4c69b62dd7a2608fd66c58e720792349f53be9508e9
3
+ metadata.gz: cd207ff4c895c9024b121bb5de205b289d8d2e54266022cfcc8e167fae2af097
4
+ data.tar.gz: c95bc639ce9adecf31ebc3c11e70a8214de31663c41be1aa539e70b1a04350f7
5
5
  SHA512:
6
- metadata.gz: cd658ca5e90d844b191ef11bbc87f5bd2f1e69cdcc07d4ce56726e3b9c23bc5c7c5056745c69d1fe95a322d67dcea131c9b8c6c14a566ee199b7d835cec508bc
7
- data.tar.gz: c6637e6f95b4b48e671f5d3a0303bb33a8327cbfec4b93da41f64e7331728578f02ca33240a37b4bc8b7c371965acbd353d9263f36f7bbc9d94062d4b3dc62fc
6
+ metadata.gz: 272d3e7b1ddad299aa58fc2fff01a2e9e336771495e04e5e279ead269ac3ac7a003621a1d7e81fcdb822b82ad61d07138b38443fe1b128403058b607a9175dad
7
+ data.tar.gz: 5b237e8afd7d7c9c098e3d0ab62e388ed09469bfb1b86874fa1c7c6ea05d9f7199bb430853f9dce81999567bfd197856a5c4514267a3d1fe5adfd6cf914fce5a
@@ -9,6 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  * Added/Changed/Deprecated/Removed/Fixed/Security: YOUR CHANGE HERE
11
11
 
12
+ ## 0.7.0 (2019-05-15)
13
+
14
+ * Added: input type now accepts `enum` param which allows create enum fields
15
+ * Added: routes now accepts `suffix: true` flag which generates GraphQL field with appended action name to the end of resource name
16
+
12
17
  ## 0.6.0 (2019-04-29)
13
18
 
14
19
  * Breaking change: controller params are always underscored [@povilasjurcys](https://github.com/povilasjurcys).
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql_rails (0.6.0)
4
+ graphql_rails (0.7.0)
5
5
  activesupport (>= 4)
6
6
  graphql (~> 1)
7
7
 
@@ -1,5 +1,9 @@
1
1
  # GraphqlRails
2
2
 
3
+ [![Build Status](https://travis-ci.org/samesystem/graphql_rails.svg?branch=master)](https://travis-ci.org/samesystem/graphql_rails)
4
+ [![codecov](https://codecov.io/gh/samesystem/graphql_rails/branch/master/graph/badge.svg)](https://codecov.io/gh/samesystem/graphql_rails)
5
+ [![Documentation](https://readthedocs.org/projects/ansicolortags/badge/?version=latest)](https://samesystem.github.io/graphql_rails)
6
+
3
7
  Rails style structure for GraphQL API.
4
8
 
5
9
  ## Installation
@@ -167,6 +171,9 @@ RSpec.describe MyGraphqlController, type: :graphql_controller do
167
171
  end
168
172
  ```
169
173
 
174
+ ## Detailed documentation
175
+
176
+ Check https://samesystem.github.io/graphql_rails for more details
170
177
 
171
178
  ## Development
172
179
 
@@ -176,7 +183,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
176
183
 
177
184
  ## Contributing
178
185
 
179
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/graphql_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
186
+ Bug reports and pull requests are welcome on GitHub at https://github.com/samesystem/graphql_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
180
187
 
181
188
  ## License
182
189
 
@@ -184,4 +191,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
184
191
 
185
192
  ## Code of Conduct
186
193
 
187
- Everyone interacting in the GraphqlRails project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/graphql_rails/blob/master/CODE_OF_CONDUCT.md).
194
+ Everyone interacting in the GraphqlRails project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/samesystem/graphql_rails/blob/master/CODE_OF_CONDUCT.md).
@@ -15,15 +15,15 @@ class User # works with any class including ActiveRecord
15
15
  end
16
16
  ```
17
17
 
18
- ## _graphql_
18
+ ## graphql
19
19
 
20
20
  This method must be called inside your model body. `grapqhl` is used for making your model convertible to graphql type.
21
21
 
22
- ### _attribute_
22
+ ## attribute
23
23
 
24
24
  Most commonly you will use `attribute` to make your model methods and attributes visible via graphql endpoint.
25
25
 
26
- #### _type_
26
+ ## attribute type
27
27
 
28
28
  Some types can be determined by attribute name, so you can skip this attribute:
29
29
 
@@ -54,7 +54,7 @@ class User
54
54
  end
55
55
  ```
56
56
 
57
- #### _property_
57
+ ### attribute property
58
58
 
59
59
  By default graphql attribute names are expected to be same as model methods/attributes, but if you want to use different name on grapqhl side, you can use `propery` option:
60
60
 
@@ -72,7 +72,7 @@ class User
72
72
  end
73
73
  ```
74
74
 
75
- #### _description_
75
+ ### attribute description
76
76
 
77
77
  You can also describe each attribute and make graphql documentation even more readable. To do so, add `description` option:
78
78
 
@@ -86,7 +86,7 @@ class User
86
86
  end
87
87
  ```
88
88
 
89
- ### _name_
89
+ ## name
90
90
 
91
91
  By default grapqhl type name will be same as model name, but you can change it via `name` method
92
92
 
@@ -100,7 +100,7 @@ class User
100
100
  end
101
101
  ```
102
102
 
103
- ### _description_
103
+ ## description
104
104
 
105
105
  To improve grapqhl documentation, you can description for your graphql type:
106
106
 
@@ -114,10 +114,87 @@ class User
114
114
  end
115
115
  ```
116
116
 
117
- ### *graphql_type*
117
+ ## graphql_type
118
118
 
119
119
  Sometimes it's handy to get raw graphql type. To do so you can call:
120
120
 
121
121
  ```ruby
122
122
  YourModel.graphql.grapqhl_type
123
123
  ```
124
+
125
+ ## input
126
+
127
+ You can define input types:
128
+
129
+ ```ruby
130
+ class User
131
+ include GraphqlRails::Model
132
+
133
+ graphql.input do |c|
134
+ c.attribute :name
135
+ end
136
+ end
137
+ ```
138
+
139
+ Also you can have multiple input types:
140
+
141
+ ```ruby
142
+ class User
143
+ include GraphqlRails::Model
144
+
145
+ graphql.input(:create) do |c|
146
+ c.attribute :name
147
+ end
148
+
149
+ graphql.input(:update) do |c|
150
+ c.attribute :id
151
+ c.attribute :name
152
+ end
153
+ end
154
+ ```
155
+
156
+ ### input attribute
157
+
158
+ Most commonly you will use `attribute` to define what kind of values your endpoint accepts
159
+
160
+ #### input type
161
+
162
+ You can specify your input attribute type. If type is not provided then type is set to `:string`.
163
+
164
+ ```ruby
165
+ class User
166
+ include GraphqlRails::Model
167
+
168
+ graphql.input do |c|
169
+ c.attribute :friends_count, type: :integer!
170
+ end
171
+ end
172
+ ```
173
+
174
+ #### input enum type
175
+
176
+ You can specify your input attribute as enum:
177
+
178
+ ```ruby
179
+ class User
180
+ include GraphqlRails::Model
181
+
182
+ graphql.input do |c|
183
+ c.attribute :favorite_fruit, enum: %i[apple orange]
184
+ end
185
+ end
186
+ ```
187
+
188
+ #### input attribute description
189
+
190
+ To improve graphql endpoint documentation, you can add description for each input attribute:
191
+
192
+ ```ruby
193
+ class User
194
+ include GraphqlRails::Model
195
+
196
+ graphql.input do |c|
197
+ c.attribute :name, description: "User's first name"
198
+ end
199
+ end
200
+ ```
@@ -30,7 +30,7 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
30
30
  end
31
31
  ```
32
32
 
33
- ## _resources_
33
+ ## resources
34
34
 
35
35
  `resources` method generates routes to `index`, `show`, `create`, `update` and `destroy` controller actions.
36
36
 
@@ -59,6 +59,20 @@ MyGraphqlSchema = GraphqlRails::Router.draw do
59
59
  end
60
60
  ```
61
61
 
62
+ #### Appending name to the end of resource name
63
+
64
+ Sometimes, especially when working with member queries, it sounds better when action name is added to the end of resource name instead of start. To do so, you can add `suffix: true` to route:
65
+
66
+ ```ruby
67
+ MyGraphqlSchema = GraphqlRails::Router.draw do
68
+ resouces :users do
69
+ query :details, on: :member, suffix: true
70
+ end
71
+ end
72
+ ```
73
+
74
+ This will generate `userDetails` field on GraphQL side.
75
+
62
76
  ## _query_ and _mutation_
63
77
 
64
78
  in case you want to have non-CRUD controller with custom actions you can define your own `query`/`mutation` actions like this:
@@ -4,7 +4,7 @@ require 'graphql_rails/version'
4
4
  require 'graphql_rails/model'
5
5
  require 'graphql_rails/router'
6
6
  require 'graphql_rails/controller'
7
- require 'graphql_rails/attribute'
7
+ require 'graphql_rails/attributes'
8
8
 
9
9
  # wonders starts here
10
10
  module GraphqlRails
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlRails
4
+ # attributes namespace
5
+ module Attributes
6
+ require_relative './attributes/attributable'
7
+ require_relative './attributes/attribute'
8
+ require_relative './attributes/input_attribute'
9
+
10
+ require_relative './attributes/type_parser'
11
+ require_relative './attributes/attribute_name_parser'
12
+ end
13
+ end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/attribute/type_parser'
4
- require 'graphql_rails/attribute/attribute_name_parser'
3
+ require 'graphql_rails/attributes/type_parser'
4
+ require 'graphql_rails/attributes/attribute_name_parser'
5
5
 
6
6
  module GraphqlRails
7
- class Attribute
7
+ module Attributes
8
8
  # contains methods which are shared between various attribute-like classes
9
9
  # expects `initial_name` and `initial_type` to be defined
10
10
  module Attributable
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+ require 'graphql_rails/attributes/attributable'
5
+
6
+ module GraphqlRails
7
+ module Attributes
8
+ # contains info about single graphql attribute
9
+ class Attribute
10
+ include Attributable
11
+
12
+ attr_reader :property, :description
13
+
14
+ def initialize(name, type = nil, description: nil, property: name)
15
+ @initial_type = type
16
+ @initial_name = name
17
+ @description = description
18
+ @property = property.to_s
19
+ end
20
+
21
+ def field_args
22
+ [field_name, graphql_field_type, { property: property.to_sym, description: description }]
23
+ end
24
+
25
+ protected
26
+
27
+ attr_reader :initial_type, :initial_name
28
+ end
29
+ end
30
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- class Attribute
4
+ module Attributes
5
5
  # Parses attribute name and can generates graphql scalar type,
6
6
  # grapqhl name and etc. based on that
7
7
  class AttributeNameParser
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- module Model
4
+ module Attributes
5
5
  # contains info about single graphql input attribute
6
6
  class InputAttribute
7
- include GraphqlRails::Attribute::Attributable
7
+ include Attributable
8
8
 
9
9
  attr_reader :description
10
10
 
@@ -3,7 +3,7 @@
3
3
  require 'graphql'
4
4
 
5
5
  module GraphqlRails
6
- class Attribute
6
+ module Attributes
7
7
  # converts string value in to GraphQL type
8
8
  class TypeParser
9
9
  class UnknownTypeError < ArgumentError; end
@@ -1,9 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/string/filters'
4
- require 'graphql_rails/attribute/type_parser'
5
- require 'graphql_rails/attribute'
6
- require 'graphql_rails/model/input_attribute'
4
+ require 'graphql_rails/attributes'
7
5
 
8
6
  module GraphqlRails
9
7
  class Controller
@@ -86,12 +84,12 @@ module GraphqlRails
86
84
  end
87
85
 
88
86
  def type_parser
89
- GraphqlRails::Attribute::TypeParser.new(custom_return_type)
87
+ Attributes::TypeParser.new(custom_return_type)
90
88
  end
91
89
 
92
90
  def permit_attribute(name, type = nil)
93
91
  field_name = name.to_s.remove(/!\Z/)
94
- attributes[field_name] = Model::InputAttribute.new(name.to_s, type, options: action_options)
92
+ attributes[field_name] = Attributes::InputAttribute.new(name.to_s, type, options: action_options)
95
93
  end
96
94
  end
97
95
  end
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'active_support/core_ext/string/inflections'
4
- require 'graphql_rails/attribute'
5
4
  require 'graphql_rails/controller/action_configuration'
6
5
  require 'graphql_rails/controller/action_hook'
7
6
 
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
+ require 'graphql'
5
+
4
6
  # base class which is returned in case something bad happens. Contains all error rendering tructure
5
7
  class ExecutionError < GraphQL::ExecutionError
6
8
  def to_h
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'graphql'
4
+ require 'graphql_rails/attributes/attributable'
5
+
6
+ module GraphqlRails
7
+ module Model
8
+ # contains info about single graphql attribute
9
+ class BuildEnumType
10
+ def self.call(*args)
11
+ new(*args).call
12
+ end
13
+
14
+ def initialize(name, allowed_values:, description: nil)
15
+ @name = name
16
+ @allowed_values = allowed_values
17
+ @description = description
18
+ end
19
+
20
+ def call
21
+ allowed_values = self.allowed_values
22
+ enum_name = name.to_s.camelize
23
+ enum_description = description
24
+
25
+ Class.new(GraphQL::Schema::Enum) do
26
+ allowed_values.each do |allowed_value|
27
+ graphql_name(enum_name)
28
+ description(enum_description) if enum_description
29
+ value(allowed_value.to_s.underscore.upcase, value: allowed_value)
30
+ end
31
+ end
32
+ end
33
+
34
+ protected
35
+
36
+ attr_reader :name, :allowed_values, :description
37
+ end
38
+ end
39
+ end
@@ -3,7 +3,11 @@
3
3
  module GraphqlRails
4
4
  module Model
5
5
  # stores information about model specific config, like attributes and types
6
- class GraphqlInputTypeBuilder
6
+ class BuildGraphqlInputType
7
+ def self.call(*args)
8
+ new(*args).call
9
+ end
10
+
7
11
  def initialize(name:, description: nil, attributes:)
8
12
  @name = name
9
13
  @attributes = attributes
@@ -3,7 +3,11 @@
3
3
  module GraphqlRails
4
4
  module Model
5
5
  # stores information about model specific config, like attributes and types
6
- class GraphqlTypeBuilder
6
+ class BuildGraphqlType
7
+ def self.call(*args)
8
+ new(*args).call
9
+ end
10
+
7
11
  def initialize(name:, description: nil, attributes:)
8
12
  @name = name
9
13
  @attributes = attributes
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/attribute'
4
- require 'graphql_rails/model/graphql_type_builder'
3
+ require 'graphql_rails/attributes'
4
+ require 'graphql_rails/model/build_graphql_type'
5
+ require 'graphql_rails/model/build_enum_type'
5
6
  require 'graphql_rails/model/input'
6
7
  require 'graphql_rails/model/configurable'
7
8
  require 'graphql_rails/model/configuration/count_items'
@@ -18,7 +19,7 @@ module GraphqlRails
18
19
 
19
20
  def attribute(attribute_name, type: nil, **attribute_options)
20
21
  attributes[attribute_name.to_s] = \
21
- Attribute.new(
22
+ Attributes::Attribute.new(
22
23
  attribute_name,
23
24
  type,
24
25
  attribute_options
@@ -35,14 +36,14 @@ module GraphqlRails
35
36
  end
36
37
 
37
38
  @input.fetch(name) do
38
- raise("GraphQL input with name #{input_name.inspect} is not defined for #{model_class}")
39
+ raise("GraphQL input with name #{input_name.inspect} is not defined for #{model_class.name}")
39
40
  end
40
41
  end
41
42
 
42
43
  def graphql_type
43
- @graphql_type ||= GraphqlTypeBuilder.new(
44
+ @graphql_type ||= BuildGraphqlType.call(
44
45
  name: name, description: description, attributes: attributes
45
- ).call
46
+ )
46
47
  end
47
48
 
48
49
  def connection_type
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'graphql_rails/model/graphql_input_type_builder'
3
+ require 'graphql_rails/model/build_graphql_input_type'
4
4
  require 'graphql_rails/model/configurable'
5
5
 
6
6
  module GraphqlRails
@@ -15,16 +15,16 @@ module GraphqlRails
15
15
  end
16
16
 
17
17
  def graphql_input_type
18
- @graphql_input_type ||= GraphqlInputTypeBuilder.new(
18
+ @graphql_input_type ||= BuildGraphqlInputType.call(
19
19
  name: name, description: description, attributes: attributes
20
- ).call
20
+ )
21
21
  end
22
22
 
23
- def attribute(attribute_name, type: nil, **attribute_options)
23
+ def attribute(attribute_name, type: nil, enum: nil, **attribute_options)
24
24
  attributes[attribute_name.to_s] = \
25
- InputAttribute.new(
25
+ GraphqlRails::Attributes::InputAttribute.new(
26
26
  attribute_name,
27
- type,
27
+ attribute_type(attribute_name, type: type, enum: enum, **attribute_options),
28
28
  attribute_options
29
29
  )
30
30
  end
@@ -39,6 +39,16 @@ module GraphqlRails
39
39
  "#{model_class.name.split('::').last}#{suffix}Input"
40
40
  end
41
41
  end
42
+
43
+ def attribute_type(attribute_name, type:, enum:, description: nil, **_other)
44
+ return type unless enum
45
+
46
+ BuildEnumType.call(
47
+ "#{name}_#{attribute_name}_enum",
48
+ allowed_values: enum,
49
+ description: description
50
+ )
51
+ end
42
52
  end
43
53
  end
44
54
  end
@@ -62,11 +62,18 @@ module GraphqlRails
62
62
  build_route(QueryRoute, *args)
63
63
  end
64
64
 
65
- def build_route(builder, action, prefix: action, on: :member, **custom_options)
65
+ # rubocop:disable Metrics/ParameterLists
66
+ def build_route(builder, action, prefix: action, suffix: false, on: :member, **custom_options)
67
+ if suffix == true
68
+ suffix_name = action
69
+ prefix = ''
70
+ end
71
+
66
72
  action_options = options.merge(custom_options).merge(on: on)
67
- action_name = [prefix, resource_name(on)].reject(&:empty?).join('_')
73
+ action_name = [prefix, resource_name(on), suffix_name].map(&:to_s).reject(&:empty?).join('_')
68
74
  builder.new(action_name, to: "#{name}##{action}", **action_options)
69
75
  end
76
+ # rubocop:enable Metrics/ParameterLists
70
77
 
71
78
  def initial_action_names(only, except, available)
72
79
  alowed_routes = Array(only || available) & available
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlRails
4
- VERSION = '0.6.0'
4
+ VERSION = '0.7.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Povilas Jurčys
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-04-29 00:00:00.000000000 Z
11
+ date: 2019-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -126,7 +126,6 @@ files:
126
126
  - Gemfile
127
127
  - Gemfile.lock
128
128
  - LICENSE.txt
129
- - README.md
130
129
  - Rakefile
131
130
  - bin/console
132
131
  - bin/setup
@@ -142,10 +141,12 @@ files:
142
141
  - docs/testing/testing.md
143
142
  - graphql_rails.gemspec
144
143
  - lib/graphql_rails.rb
145
- - lib/graphql_rails/attribute.rb
146
- - lib/graphql_rails/attribute/attributable.rb
147
- - lib/graphql_rails/attribute/attribute_name_parser.rb
148
- - lib/graphql_rails/attribute/type_parser.rb
144
+ - lib/graphql_rails/attributes.rb
145
+ - lib/graphql_rails/attributes/attributable.rb
146
+ - lib/graphql_rails/attributes/attribute.rb
147
+ - lib/graphql_rails/attributes/attribute_name_parser.rb
148
+ - lib/graphql_rails/attributes/input_attribute.rb
149
+ - lib/graphql_rails/attributes/type_parser.rb
149
150
  - lib/graphql_rails/controller.rb
150
151
  - lib/graphql_rails/controller/action.rb
151
152
  - lib/graphql_rails/controller/action_configuration.rb
@@ -159,13 +160,13 @@ files:
159
160
  - lib/graphql_rails/errors/execution_error.rb
160
161
  - lib/graphql_rails/errors/validation_error.rb
161
162
  - lib/graphql_rails/model.rb
163
+ - lib/graphql_rails/model/build_enum_type.rb
164
+ - lib/graphql_rails/model/build_graphql_input_type.rb
165
+ - lib/graphql_rails/model/build_graphql_type.rb
162
166
  - lib/graphql_rails/model/configurable.rb
163
167
  - lib/graphql_rails/model/configuration.rb
164
168
  - lib/graphql_rails/model/configuration/count_items.rb
165
- - lib/graphql_rails/model/graphql_input_type_builder.rb
166
- - lib/graphql_rails/model/graphql_type_builder.rb
167
169
  - lib/graphql_rails/model/input.rb
168
- - lib/graphql_rails/model/input_attribute.rb
169
170
  - lib/graphql_rails/router.rb
170
171
  - lib/graphql_rails/router/mutation_route.rb
171
172
  - lib/graphql_rails/router/plain_cursor_encoder.rb
data/README.md DELETED
@@ -1,194 +0,0 @@
1
- # GraphqlRails
2
-
3
- [![Build Status](https://travis-ci.org/samesystem/graphql_rails.svg?branch=master)](https://travis-ci.org/samesystem/graphql_rails)
4
- [![codecov](https://codecov.io/gh/samesystem/graphql_rails/branch/master/graph/badge.svg)](https://codecov.io/gh/samesystem/graphql_rails)
5
- [![Documentation](https://readthedocs.org/projects/ansicolortags/badge/?version=latest)](https://samesystem.github.io/graphql_rails)
6
-
7
- Rails style structure for GraphQL API.
8
-
9
- ## Installation
10
-
11
- Add this line to your application's Gemfile:
12
-
13
- ```ruby
14
- gem 'graphql_rails'
15
- ```
16
-
17
- And then execute:
18
-
19
- $ bundle
20
-
21
- Or install it yourself as:
22
-
23
- $ gem install graphql_rails
24
-
25
- ## Usage
26
-
27
- ### Define GraphQL schema as RoR routes
28
-
29
- ```ruby
30
- MyGraphqlSchema = GraphqlRails::Router.draw do
31
- # will create createUser, updateUser, deleteUser mutations and user, users queries.
32
- # expects that UsersController class exist
33
- resources :users
34
-
35
- # if you want custom queries or mutation
36
- query 'searchLogs', to: 'logs#search' # redirects request to LogsController
37
- mutation 'changeUserPassword', to: 'users#change_password'
38
- end
39
- ```
40
-
41
- ### Define your Graphql model
42
-
43
- ```ruby
44
- class User # works with any class including ActiveRecord
45
- include GraphqlRails::Model
46
-
47
- graphql do |c|
48
- # most common attributes, like :id, :name, :title has default type, so you don't have to specify it (but you can!)
49
- c.attribute :id
50
-
51
- c.attribute :email, type: :string
52
- c.attribute :surname, type: :string
53
- end
54
- end
55
- ```
56
-
57
- ### Define controller
58
-
59
- ```ruby
60
- class UsersController < GraphqlRails::Controller
61
- # graphql requires to describe which attributes controller action accepts and which returns
62
- action(:change_user_password)
63
- .permit(:password!, :id!) # Bang (!) indicates that attribute is required
64
-
65
- def change_user_password
66
- user = User.find(params[:id])
67
- user.update!(password: params[:password])
68
-
69
- # returned value needs to have all methods defined in model `graphql do` part
70
- user # or SomeDecorator.new(user)
71
- end
72
-
73
- action(:search).permit(search_fields!: SearchFieldsInput) # you can specify your own input fields
74
- def search
75
- end
76
- end
77
- ```
78
-
79
- ## Routes
80
-
81
- ```ruby
82
- MyGraphqlSchema = GraphqlRails::Router.draw do
83
- # generates `friend`, `createFriend`, `updateFriend`, `destroyFriend`, `friends` routes
84
- resources :friends
85
- resources :shops, only: [:show, :index] # generates `shop` and `shops` routes only
86
- resources :orders, except: :update # generates all routes except `updateOrder`
87
-
88
- resources :users do
89
- # generates `findUser` query
90
- query :find, on: :member
91
-
92
- # generates `searchUsers` query
93
- query :search, on: :collection
94
- end
95
-
96
- # you can use namespaced controllers too:
97
- scope module: 'admin' do
98
- # `updateTranslations` route will be handeled by `Admin::TranslationsController`
99
- mutation :updateTranslations, to: 'translations#update'
100
-
101
- # all :groups routes will be handeled by `Admin::GroupsController`
102
- resources :groups
103
- end
104
- end
105
- ```
106
-
107
- ## Testing your GraphqlRails::Controller in RSpec
108
-
109
- ### Setup
110
-
111
- Add those lines in your `spec/spec_helper.rb` file
112
-
113
- ```ruby
114
- # spec/spec_helper.rb
115
- require 'graphql_rails/rspec_controller_helpers'
116
-
117
- RSpec.configure do |config|
118
- config.include(GraphqlRails::RSpecControllerHelpers, type: :graphql_controller)
119
- # ... your other configuration ...
120
- end
121
- ```
122
-
123
- ### Helper methods
124
-
125
- There are 3 helper methods:
126
-
127
- * `mutation(:your_controller_action_name, params: {}, context: {})`. `params` and `context` are optional
128
- * `query(:your_controller_action_name, params: {}, context: {})`. `params` and `context` are optional
129
- * `response`. Response is set only after you call `mutation` or `query`
130
-
131
- ### Test examples
132
-
133
- ```ruby
134
- class MyGraphqlController
135
- def index
136
- "Called from index: #{params[:message]}"
137
- end
138
-
139
- action(:create_user).permit(:full_name, :email)
140
- def create_user
141
- User.create!(params)
142
- end
143
- end
144
-
145
- RSpec.describe MyGraphqlController, type: :graphql_controller do
146
- describe '#index' do
147
- it 'is successful' do
148
- query(:index)
149
- expect(response).to be_successful
150
- end
151
-
152
- it 'returns correct message' do
153
- query(:index, params: { message: 'Hello world!' })
154
- expect(response.result).to eq "Called from index: Hello world!"
155
- end
156
- end
157
-
158
- describe '#create_user' do
159
- context 'when bad email is given' do
160
- it 'fails' do
161
- mutation(:create_user, params { email: 'bad' })
162
- expect(response).to be_failure
163
- end
164
-
165
- it 'contains errors' do
166
- mutation(:create_user, params { email: 'bad' })
167
- expect(response.errors).not_to be_empty
168
- end
169
- end
170
- end
171
- end
172
- ```
173
-
174
- ## Detailed documentation
175
-
176
- Check https://samesystem.github.io/graphql_rails for more details
177
-
178
- ## Development
179
-
180
- After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
181
-
182
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
183
-
184
- ## Contributing
185
-
186
- Bug reports and pull requests are welcome on GitHub at https://github.com/samesystem/graphql_rails. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
187
-
188
- ## License
189
-
190
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
191
-
192
- ## Code of Conduct
193
-
194
- Everyone interacting in the GraphqlRails project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/samesystem/graphql_rails/blob/master/CODE_OF_CONDUCT.md).
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'graphql'
4
- require 'graphql_rails/attribute/attributable'
5
-
6
- module GraphqlRails
7
- # contains info about single graphql attribute
8
- class Attribute
9
- include Attributable
10
-
11
- attr_reader :property, :description
12
-
13
- def initialize(name, type = nil, description: nil, property: name)
14
- @initial_type = type
15
- @initial_name = name
16
- @description = description
17
- @property = property.to_s
18
- end
19
-
20
- def field_args
21
- [field_name, graphql_field_type, { property: property.to_sym, description: description }]
22
- end
23
-
24
- protected
25
-
26
- attr_reader :initial_type, :initial_name
27
- end
28
- end