graphql_connector 0.1.0.beta1 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fc6fbc6e76e115e9f9b9cbc0a17c5e09d6404f0f3f688e69095fa80ef308c59a
4
- data.tar.gz: 2159568d552c24a25a37d8233e06e125eedc3a4598a76f4a201818b105c6e787
3
+ metadata.gz: 76343e24e10c4dd1cf216693639ca283fa96c6562e10432b7815f57effd07171
4
+ data.tar.gz: 83f6e99ac9d87619e2464d7436493ccc0eaa79b2a27cf9d60103e806fe2d09aa
5
5
  SHA512:
6
- metadata.gz: 42ee8bbcdde2f68eea168e251259892aa06b617f5fd67735a7833af78c3d2c1341bb26befd10078df1e63b288ab23cb5f3d94df8754d96836801e09a2ed42895
7
- data.tar.gz: 973006929bc4e2fde380dc6d7b7228f01a506ef2b34ee610c73515643ee6b74052dbad134ce9b33ad2e0bac95c04f9fd54d71132eb48b717f08990136e7ddd49
6
+ metadata.gz: 725ae753055da95a57738ce5581e9e877bbd54c0511eab2726e2b415701e9be8ca1dd3e5db201af8cbdadc0e70e855ee90f7c7bc58a9e95591fbe19a6eb4c58f
7
+ data.tar.gz: 3f4b4ecfe3ea1a75010c94e9d8dab85b192ef254a84f913f635584d814689d6fabca96d416c74ed75acfb1acb12a02397d0353b10effe6ad8d8d7b0fa75c6564
@@ -0,0 +1,37 @@
1
+ name: CI
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ ruby: ['2.4.x', '2.5.x', '2.6.x', '2.7.x']
11
+ name: "ruby ${{ matrix.ruby }}"
12
+ steps:
13
+ - uses: actions/checkout@v1
14
+ - uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.ruby }}
17
+ - name: Install dependencies
18
+ run: |
19
+ gem install bundler
20
+ bundle install
21
+ - name: Run Test with rspec
22
+ run: bundle exec rspec spec
23
+ rubocop:
24
+ name: Rubocop
25
+ runs-on: ubuntu-latest
26
+ steps:
27
+ - uses: actions/checkout@v2
28
+ - uses: actions/setup-ruby@v1
29
+ with:
30
+ ruby-version: 2.7.x
31
+ - name: Install dependencies
32
+ run: |
33
+ gem install bundler
34
+ bundle install
35
+ - name: Build and test
36
+ run: |
37
+ bundle exec rubocop
data/.rspec CHANGED
@@ -1 +1,2 @@
1
1
  --require spec_helper
2
+ --order rand
@@ -0,0 +1,2 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
@@ -0,0 +1,6 @@
1
+ Lint/DuplicateMethods:
2
+ Exclude:
3
+ - lib/graphql_connector.rb
4
+ Metrics/BlockLength:
5
+ Exclude:
6
+ - spec/graphql_connector/**/*.rb
@@ -1,14 +1,43 @@
1
+ ## 1.2.0 (2020-12-22)
1
2
 
2
- ### 0.1.0 Init
3
+ ### Features
4
+ * Add `mutation` under server namespace and service class inclusion
5
+ * See `README` for details
3
6
 
4
- TBA
7
+ ## 1.1.1 (2020-5-04)
5
8
 
6
- ### 0.1.0.beta1
9
+ ### BugFix
10
+ * Omit invalid `()` for empty conditions in `query` method
7
11
 
8
- ** BugFix
9
- use model instead of hardcoded product
12
+ ## 1.1.0 (2020-4-19)
10
13
 
14
+ ### Features
15
+ * Allow building graphql querying in custom classes via `service class inclusion`
16
+ * See `README` for details about `service class inclusion`
11
17
 
12
- ### 0.1.0.beta
18
+ ### BugFix
19
+ * Forward `variables` when performing a `raw_query`
13
20
 
14
- easy graphql logic
21
+ ## 1.0.0 (2020-1-26)
22
+
23
+ ### Breaking
24
+ * add multiple graphql server querying
25
+ * `query` and `raw_query` nested under server namespace
26
+
27
+
28
+ ## 0.2.0 (2019-11-19)
29
+
30
+ ### Features
31
+ * new `raw_query` method. you have to write the graphql query
32
+ string by your self and also you get only the parsed json back.
33
+ * query supports associations for the selected_fields attribute
34
+
35
+ ## 0.1.0.beta1 (2019-10-06)
36
+
37
+ ### BugFix
38
+ * use model instead of hardcoded product
39
+
40
+
41
+ ## 0.1.0.beta (2019-10-03)
42
+
43
+ * easy graphql logic
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- graphql_connector (0.1.0.beta1)
4
+ graphql_connector (1.2.0)
5
5
  httparty (~> 0.17)
6
6
 
7
7
  GEM
@@ -10,45 +10,46 @@ GEM
10
10
  ast (2.4.0)
11
11
  coderay (1.1.2)
12
12
  diff-lcs (1.3)
13
- httparty (0.17.1)
13
+ httparty (0.18.0)
14
14
  mime-types (~> 3.0)
15
15
  multi_xml (>= 0.5.2)
16
- jaro_winkler (1.5.3)
17
- method_source (0.9.2)
18
- mime-types (3.3)
16
+ jaro_winkler (1.5.4)
17
+ method_source (1.0.0)
18
+ mime-types (3.3.1)
19
19
  mime-types-data (~> 3.2015)
20
- mime-types-data (3.2019.0904)
20
+ mime-types-data (3.2019.1009)
21
21
  multi_xml (0.6.0)
22
- parallel (1.17.0)
23
- parser (2.6.5.0)
22
+ parallel (1.19.1)
23
+ parser (2.7.1.1)
24
24
  ast (~> 2.4.0)
25
- pry (0.12.2)
26
- coderay (~> 1.1.0)
27
- method_source (~> 0.9.0)
25
+ pry (0.13.1)
26
+ coderay (~> 1.1)
27
+ method_source (~> 1.0)
28
28
  rainbow (3.0.0)
29
- rake (10.5.0)
30
- rspec (3.8.0)
31
- rspec-core (~> 3.8.0)
32
- rspec-expectations (~> 3.8.0)
33
- rspec-mocks (~> 3.8.0)
34
- rspec-core (3.8.2)
35
- rspec-support (~> 3.8.0)
36
- rspec-expectations (3.8.5)
29
+ rexml (3.2.4)
30
+ rspec (3.9.0)
31
+ rspec-core (~> 3.9.0)
32
+ rspec-expectations (~> 3.9.0)
33
+ rspec-mocks (~> 3.9.0)
34
+ rspec-core (3.9.1)
35
+ rspec-support (~> 3.9.1)
36
+ rspec-expectations (3.9.1)
37
37
  diff-lcs (>= 1.2.0, < 2.0)
38
- rspec-support (~> 3.8.0)
39
- rspec-mocks (3.8.2)
38
+ rspec-support (~> 3.9.0)
39
+ rspec-mocks (3.9.1)
40
40
  diff-lcs (>= 1.2.0, < 2.0)
41
- rspec-support (~> 3.8.0)
42
- rspec-support (3.8.3)
43
- rubocop (0.75.0)
41
+ rspec-support (~> 3.9.0)
42
+ rspec-support (3.9.2)
43
+ rubocop (0.82.0)
44
44
  jaro_winkler (~> 1.5.1)
45
45
  parallel (~> 1.10)
46
- parser (>= 2.6)
46
+ parser (>= 2.7.0.1)
47
47
  rainbow (>= 2.2.2, < 4.0)
48
+ rexml
48
49
  ruby-progressbar (~> 1.7)
49
- unicode-display_width (>= 1.4.0, < 1.7)
50
+ unicode-display_width (>= 1.4.0, < 2.0)
50
51
  ruby-progressbar (1.10.1)
51
- unicode-display_width (1.6.0)
52
+ unicode-display_width (1.7.0)
52
53
 
53
54
  PLATFORMS
54
55
  ruby
@@ -57,9 +58,8 @@ DEPENDENCIES
57
58
  bundler (~> 2.0)
58
59
  graphql_connector!
59
60
  pry (~> 0.10)
60
- rake (~> 10.0)
61
61
  rspec (~> 3.8)
62
62
  rubocop (~> 0.75)
63
63
 
64
64
  BUNDLED WITH
65
- 2.0.2
65
+ 2.1.4
data/README.md CHANGED
@@ -1,12 +1,13 @@
1
+
1
2
  # GraphqlConnector
2
3
 
3
4
  [![Gem
4
5
  Version](https://badge.fury.io/rb/graphql_connector.svg)](https://badge.fury.io/rb/graphql_connector)
5
- [![Build
6
- Status](https://travis-ci.org/Garllon/graphql_connector.svg?branch=master)](https://travis-ci.org/Garllon/graphql_connector)
6
+ [![CI](https://github.com/Garllon/graphql_connector/workflows/CI/badge.svg)](https://github.com/Garllon/graphql_connector/actions?query=workflow%3ACI)
7
+ [![Maintainability](https://api.codeclimate.com/v1/badges/548db3cf0d078b379c84/maintainability)](https://codeclimate.com/github/Garllon/graphql_connector/maintainability)
7
8
 
8
- An easy connector to call your `graphql` server.
9
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/graphql_connector`. To experiment with that code, run `bin/console` for an interactive prompt.
9
+ An easy connector to call your `graphql` server. Currently there is no schema
10
+ check in the code, but i will add it.
10
11
 
11
12
  ## Installation
12
13
 
@@ -29,21 +30,188 @@ Or install it yourself as:
29
30
  You need to configure the `graphql_connector` first:
30
31
  ``` ruby
31
32
  GraphqlConnector.configure do |config|
32
- config.host = ''
33
- config.headers = {}
33
+ config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
34
34
  end
35
35
  ```
36
36
 
37
- Then you can call your graphql_endpoint:
37
+ For each graphql server you wish to query use `add_server`.
38
+
39
+ Afterwards you will have the following options to fetch and/or mutate data with
40
+ one or many graphql servers:
41
+
42
+ * `raw_query` --> [Examples](examples/raw_query_examples.rb)
43
+ * `query` --> [Examples](examples/query_examples.rb)
44
+ * `mutation` --> [Examples](examples/mutation_examples.rb)
45
+ * `service class inclusion` --> [Examples](examples/departments_service_class_examples.rb)
46
+
47
+ See the following sub sections for details
48
+
49
+ ### raw_query
50
+
51
+ You can call your graphql_endpoint via:
52
+ ```ruby
53
+ GraphqlConnector::<name>.raw_query(query_string)
54
+ ```
55
+
56
+ Note that `<name>` has to be replaced by any of the ones added via `add_server`
57
+
58
+ See also [here](examples/raw_query_examples.rb) for example usage
59
+
60
+ ---
61
+ ### query
62
+
63
+ You can also use the more comfortable `query`:
38
64
  ```ruby
39
- GraphqlConnector.query(model, condition, selected_fields)
65
+ GraphqlConnector::<name>.query(model, condition, selected_fields)
66
+ ```
67
+
68
+ | Variable | DataType | Example |
69
+ |----------------|-------------------------|------------------------------------------|
70
+ | model | String | 'product' |
71
+ | condition | Hash(key, value) | { id: 1 } |
72
+ | selected_fields | Array of Strings/Hashes | ['id', 'name', productCategory: ['id']] |
73
+
74
+ > Caution:
75
+ > You get an OpenStruct back. Currently only the first level attributes are
76
+ > supported with OpenStruct, associated objects are still a normal array of
77
+ > hashes.
78
+
79
+ See also [here](examples/query_examples.rb) for example usage
80
+
81
+ #### selected_fields
82
+
83
+ The syntax for the associations looks like the following:
84
+ ```
85
+ ['<attribute_name>', <association_name>: ['<attribute_name_of_the_association>']]
40
86
  ```
41
87
 
42
- | Variable | DataType | Example |
43
- | ----------------|------------------| ---------------|
44
- | model | String | 'product' |
45
- | condition | Hash(key, value) | { id: 1 } |
46
- | selected_fields | Array of Strings | ['id', 'name'] |
88
+ Example:
89
+ ```ruby
90
+ ['id', 'name', productCategory: ['id', 'name']]
91
+ ```
92
+
93
+ ---
94
+
95
+ ### mutation
96
+
97
+ Works in the same way as [query](#query)
98
+
99
+ See also [here](examples/mutation_examples.rb) for example usage
100
+
101
+ ### Service class inclusion
102
+
103
+ This approach can be used to `graphqlize` **any** kind of ruby (service) class
104
+ so that it has re-usable graphql `query` and `mutation` **class methods**.
105
+
106
+ * First add `extend GraphqlConnector::<server>::Query` in the the class(es) that should be `graphqlized`
107
+
108
+ * Then you can aliases as many graphql server types via `add_query` and/or `add_raw_query` and/or `add_mutation`:
109
+
110
+ ```ruby
111
+ add_query <alias>: :<graphql_server_type>, params: [...], returns: [...]
112
+
113
+ add_raw_query <alias>: 'query { ... }', params: [...]
114
+
115
+ add_mutation <alias>: :<graphql_server_type>, params: [...], returns: [...]
116
+ ```
117
+ * :grey_exclamation: If not needed omit `params`
118
+
119
+ See also [here](examples/departments_service_class_examples.rb) and also here for complete example usage:
120
+
121
+ ```ruby
122
+ GraphqlConnector.configure do |config|
123
+ config.add_server(name: 'Foo', uri: 'http://foo.com/api/graphql', headers: {})
124
+ end
125
+
126
+ # product.rb
127
+ class Product
128
+ extend GraphqlConnector::Foo::Query
129
+
130
+ add_query all: :products,
131
+ returns: [:id, :name]
132
+
133
+ add_query by_id: :products,
134
+ params: :id,
135
+ returns: [:name, product_category: [:id, :name]]
136
+
137
+ add_query by_names: :products,
138
+ params: :names,
139
+ returns: [:id, :name, product_category: [:id, :name]]
140
+
141
+ add_query by: :products,
142
+ params: [:id, :name],
143
+ returns: [:name]
144
+
145
+ add_query by_category_id: :products,
146
+ params: :product_category,
147
+ returns: [product_category: [:id, :name]]
148
+
149
+ add_mutation create: :createProduct,
150
+ params: [:name, :catgetoryId],
151
+ returns: [:id, :name]
152
+ end
153
+
154
+ Product.all
155
+ => [OpenStruct<id=1, name='Demo Product', ...]
156
+
157
+ Product.by_id(id: 1)
158
+ => [OpenStruct<name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>]
159
+
160
+ Product.by_names(names: ['Demo Product', 'Non Demo Product'])
161
+ => [OpenStruct<id=1, name='Demo Product', product_category=<ProductCategory<id=10, name='Demo Category'>>, Product<id=2, name='Demo Product' ...]
162
+
163
+ Product.by(id: 1, name: 'Demo Product')
164
+ => OpenStruct<name='Demo Product'>
165
+
166
+ Product.by_category_id(product_category: { id: 10})
167
+ => OpenStruct<product_category=<ProductCategory<id=10, name='Demo Category'>>
168
+
169
+ Product.create(name: 'Another Product', catgetoryId: 10)
170
+ => OpenStruct<id=10, name='Another Product'>
171
+ ```
172
+
173
+ Also custom **class methods** can used to call any kind of `query` and do further selection instead:
174
+
175
+ ```ruby
176
+ class Product
177
+ extend GraphqlConnector::Foo::Query
178
+
179
+ add_query all: :products, returns: [:name]
180
+
181
+ def self.by_id(id:)
182
+ all.select { |products| products.id == id }.first
183
+ end
184
+ end
185
+
186
+ Product.by_id(id: 1)
187
+ => OpenStruct<id=1, name='Demo Product'>>
188
+ ```
189
+
190
+ :warning: Ensure that your custom **class method** never has the **same name** as an `<alias>` of `add_query`, `add_raw_query` or `add_mutation`. Otherwise the associated grapqhl query will not be performed because of [Ruby Open Class principle](https://ruby-lang.co/ruby-open-class/)
191
+
192
+
193
+ Example for `raw_query`:
194
+
195
+ ```ruby
196
+ class Product
197
+ extend GraphqlConnector::Foo::Query
198
+
199
+ add_raw_query all: ' query { products { id name } } '
200
+ add_raw_query by: ' query products($id: !ID, $name: !String) '\
201
+ '{ products(id: $id, name: $name) { id name } }',
202
+ params: [:id, :name]
203
+
204
+ end
205
+
206
+ Product.all
207
+ => [ { id: '1', name: 'Demo Product' }, ...]
208
+
209
+ Product.by(id: '1', name: 'Demo Product')
210
+ => { id: '1', name: 'Demo Product' }
211
+
212
+ ```
213
+
214
+ :exclamation: There is no `add_raw_mutation` since `add_raw_query` does already cover such a case
47
215
 
48
216
  ## Development
49
217
 
@@ -53,12 +221,15 @@ bundle install
53
221
  ```
54
222
 
55
223
  Then, run
56
- ```bundle exec rspec spec` to run the tests.
224
+ ```shell
225
+ bundle exec rspec spec
226
+ ```
227
+ to run the tests.
57
228
  You can also run `bin/console` for an interactive prompt that will allow you to experiment.
58
229
 
59
230
  ## Contributing
60
231
 
61
- Bug reports and pull requests are welcome on GitHub at https://github.com/garllon/graphql_connector. 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.
232
+ Bug reports and pull requests are welcome on GitHub at [https://github.com/garllon/graphql_connector](https://github.com/garllon/graphql_connector). 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.
62
233
 
63
234
  ## License
64
235
 
@@ -66,4 +237,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
66
237
 
67
238
  ## Code of Conduct
68
239
 
69
- Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/graphql_connector/blob/master/CODE_OF_CONDUCT.md).
240
+ Everyone interacting in the GraphqlConnector project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/Garllon/graphql_connector/blob/master/CODE_OF_CONDUCT.md).
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4
+ # ! The following examples are used together with
5
+ # ! https://github.com/sushie1984/rails-graphql-server
6
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7
+
8
+ uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
9
+ GraphqlConnector.configure do |config|
10
+ config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
11
+ end
12
+
13
+ # Service class for fetching department data
14
+ class Department
15
+ extend GraphqlConnector::RailsGraphqlServer::Query
16
+
17
+ add_query all: :departments, returns: [:id, :name, employees: [:yearlySalary]]
18
+
19
+ add_query by_id: :departments,
20
+ params: [:id],
21
+ returns: [:id, :name, employees: [:yearlySalary]]
22
+
23
+ add_raw_query all_raw: 'query {
24
+ departments {
25
+ id name employees { yearlySalary }
26
+ }
27
+ }'
28
+
29
+ add_raw_query by_id_raw: 'query departments($id: [ID!]) {
30
+ departments(id: $id) {
31
+ name employees { name }
32
+ }
33
+ }',
34
+ params: [:id]
35
+
36
+ # We use a nested 'input' as of convention for
37
+ # https://github.com/sushie1984/rails-graphql-server/blob/master/app/graphql/input_objects/department_attributes.rb
38
+ add_mutation create: :createDepartment,
39
+ params: :input,
40
+ returns: [department: %i[id name location]]
41
+ end
42
+
43
+ Department.all
44
+
45
+ Department.by_id(id: %w[1 2])
46
+
47
+ Department.all_raw
48
+
49
+ Department.by_id_raw(id: %w[1 2])
50
+
51
+ Department.create(input: { attributes: { name: 'One', location: 'Berlin' } })
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4
+ # ! The following examples are used together with
5
+ # ! https://github.com/sushie1984/rails-graphql-server
6
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7
+
8
+ uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
9
+ GraphqlConnector.configure do |config|
10
+ config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
11
+ end
12
+
13
+ department_input = { attributes: { name: 'One', location: 'Berlin' } }
14
+ return_fields = ['department': ['id', 'name', 'employees' => ['yearlySalary']]]
15
+ GraphqlConnector::RailsGraphqlServer.mutation('createDepartment',
16
+ { input: department_input },
17
+ return_fields)
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4
+ # ! The following examples are used together with
5
+ # ! https://github.com/sushie1984/rails-graphql-server
6
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7
+
8
+ uri = 'http://rails-graphql-server.herokuapp.com/api/graphql'
9
+ GraphqlConnector.configure do |config|
10
+ config.add_server(name: 'RailsGraphqlServer', uri: uri, headers: {})
11
+ end
12
+
13
+ GraphqlConnector::RailsGraphqlServer.query('departments',
14
+ {},
15
+ ['id', 'name',
16
+ 'employees' => ['yearlySalary']])
17
+
18
+ GraphqlConnector::RailsGraphqlServer.query('departments',
19
+ { id: %w[1 2] },
20
+ ['id', 'name',
21
+ 'employees' => ['yearlySalary']])
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
4
+ # ! The following examples are used together with
5
+ # ! https://github.com/sushie1984/rails-graphql-server
6
+ # !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7
+
8
+ GraphqlConnector.configure do |config|
9
+ config.add_server(name: 'RailsGraphqlServer',
10
+ uri: 'http://rails-graphql-server.herokuapp.com/api/graphql',
11
+ headers: {})
12
+ end
13
+
14
+ GraphqlConnector::RailsGraphqlServer.raw_query(
15
+ 'query { departments { id name employees { yearlySalary } } }'
16
+ )
17
+
18
+ GraphqlConnector::RailsGraphqlServer.raw_query(
19
+ 'query departments($id: [ID!]) {
20
+ departments(id: $id) { name employees { name }
21
+ }
22
+ }',
23
+ variables: { id: %w[1 2] }
24
+ )
@@ -7,11 +7,13 @@ require 'graphql_connector/version'
7
7
  Gem::Specification.new do |spec|
8
8
  spec.name = 'graphql_connector'
9
9
  spec.version = GraphqlConnector::VERSION
10
- spec.authors = ['Garllon']
11
- spec.email = ['palluthe.bennet@gmail.com']
10
+ spec.authors = %w[Garllon sushie1984]
11
+ spec.email = ['palluthe.bennet@gmail.com', 'sascha_burku@yahoo.de']
12
12
 
13
- spec.summary = 'Hallo'
14
- spec.description = 'Hallo'
13
+ spec.summary = 'GraphQL client'
14
+ spec.description = 'Grahql client to query with your own raw string, '\
15
+ 'with the small helper method query or with service '\
16
+ 'class inclusion.'
15
17
  spec.homepage = 'https://github.com/Garllon/graphql_connector/blob/master/README.md'
16
18
  spec.license = 'MIT'
17
19
 
@@ -20,7 +22,8 @@ Gem::Specification.new do |spec|
20
22
  spec.metadata['changelog_uri'] = 'https://github.com/Garllon/graphql_connector/blob/master/CHANGELOG.md'
21
23
 
22
24
  # Specify which files should be added to the gem when it is released.
23
- # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
25
+ # The `git ls-files -z` loads the files in the RubyGem that have been added
26
+ # into git.
24
27
  spec.files = Dir.chdir(File.expand_path(__dir__)) do
25
28
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(spec|features)/}) }
26
29
  end
@@ -32,7 +35,6 @@ Gem::Specification.new do |spec|
32
35
 
33
36
  spec.add_development_dependency 'bundler', '~> 2.0'
34
37
  spec.add_development_dependency 'pry', '~> 0.10'
35
- spec.add_development_dependency 'rake', '~> 10.0'
36
38
  spec.add_development_dependency 'rspec', '~> 3.8'
37
39
  spec.add_development_dependency 'rubocop', '~> 0.75'
38
40
  end
@@ -1,10 +1,22 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'graphql_connector/version'
4
- require 'graphql_connector/query_builder'
4
+ require 'graphql_connector/formatters/base_format'
5
+ require 'graphql_connector/formatters/query_format'
6
+ require 'graphql_connector/formatters/mutation_format'
5
7
  require 'graphql_connector/configuration'
8
+ require 'graphql_connector/http_client'
9
+ require 'graphql_connector/base_server_type'
10
+ require 'graphql_connector/service_classable/class_method_validator'
11
+ require 'graphql_connector/service_classable/params_validator'
12
+ require 'graphql_connector/service_classable/return_fields_validator'
13
+ require 'graphql_connector/service_classable/queryable'
14
+ require 'graphql_connector/custom_attribute_error'
6
15
  require 'httparty'
7
16
 
17
+ # Main file of the GraphQLConnector
18
+ # the main methods to configure the gem
19
+ # and to run a raw_query or a normal query.
8
20
  module GraphqlConnector
9
21
  class << self
10
22
  attr_accessor :configuration
@@ -15,19 +27,10 @@ module GraphqlConnector
15
27
  end
16
28
 
17
29
  def self.reset
18
- @configuration = Configuration.new
30
+ @configuration.reset!
19
31
  end
20
32
 
21
33
  def self.configure
22
34
  yield(configuration)
23
35
  end
24
-
25
- def self.query(model, conditions, selected_fields)
26
- query_string = QueryBuilder.new(model, conditions, selected_fields).create
27
- response = HTTParty.post(GraphqlConnector.configuration.host,
28
- headers: GraphqlConnector.configuration.headers,
29
- body: { query: query_string })
30
- parsed_body = JSON.parse(response.body)
31
- OpenStruct.new(parsed_body['data'][model])
32
- end
33
36
  end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ class BaseServerTypeAlreadyExistsError < StandardError; end
5
+ # Class to wrap http_client calls under a specific namespaced class
6
+ class BaseServerType
7
+ class << self
8
+ def build(name, uri, headers)
9
+ verify_new_client_type_for!(name)
10
+ base_class = class_with(uri, headers)
11
+ base_object = GraphqlConnector.const_set(name, base_class)
12
+ inject_http_client_delegations(base_object)
13
+ create_service_class_module(base_object)
14
+
15
+ base_object
16
+ end
17
+
18
+ private
19
+
20
+ def verify_new_client_type_for!(name)
21
+ return unless GraphqlConnector.const_defined?(name)
22
+
23
+ raise BaseServerTypeAlreadyExistsError,
24
+ "The name: #{name} is already in use. Check your "\
25
+ 'configuration!'
26
+ end
27
+
28
+ def create_service_class_module(base_object)
29
+ base_object.class_eval <<-METHOD, __FILE__, __LINE__ + 1
30
+ module Query
31
+ def self.extended(base)
32
+ base.extend(GraphqlConnector::ServiceClassable::Queryable)
33
+ end
34
+
35
+ def http_client
36
+ #{base_object}.http_client
37
+ end
38
+ end
39
+ METHOD
40
+ end
41
+
42
+ def class_with(uri, headers)
43
+ Class.new do
44
+ attr_accessor :uri, :headers
45
+ @uri = uri
46
+ @headers = headers
47
+ end
48
+ end
49
+
50
+ def inject_http_client_delegations(base_object)
51
+ base_object.instance_eval do
52
+ extend SingleForwardable
53
+ def_delegators :http_client, :query, :raw_query, :mutation
54
+
55
+ def http_client
56
+ @http_client ||= GraphqlConnector::HttpClient.new(@uri, @headers)
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -1,12 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlConnector
4
+ # The configuration template file for the gem.
4
5
  class Configuration
5
- attr_accessor :host, :headers
6
+ attr_reader :base_server_types
6
7
 
7
8
  def initialize
8
- @host = nil
9
- @headers = nil
9
+ @base_server_types = {}
10
+ end
11
+
12
+ def add_server(name:, uri:, headers:)
13
+ @base_server_types[name] = BaseServerType.build(name, uri, headers)
14
+ end
15
+
16
+ def reset!
17
+ @base_server_types.keys.each do |name|
18
+ GraphqlConnector.const_get(name).send :remove_const, 'Query'
19
+ GraphqlConnector.send :remove_const, name
20
+ end
21
+ @base_server_types = {}
10
22
  end
11
23
  end
12
24
  end
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CustomAttributeError < StandardError; end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module Formatters
5
+ # Class that returns in query or mutation string format
6
+ class BaseFormat
7
+ def initialize(model, conditions, selected_fields)
8
+ @model = model
9
+ @conditions = conditions
10
+ @selected_fields = selected_fields
11
+ end
12
+
13
+ def create
14
+ <<-STRING
15
+ #{query_type} {
16
+ #{@model}#{arguments} {
17
+ #{parse_fields(@selected_fields)}
18
+ }
19
+ }
20
+ STRING
21
+ end
22
+
23
+ private
24
+
25
+ def arguments
26
+ conditions = @conditions.each_with_object([]) do |(key, value), array|
27
+ array << "#{key}: #{value_as_parameter(value)}"
28
+ end
29
+
30
+ return '' if conditions.empty?
31
+
32
+ "(#{conditions.join(', ')})"
33
+ end
34
+
35
+ def value_as_parameter(value)
36
+ case value
37
+ when Array
38
+ casted_values = value.map { |v| value_as_parameter(v) }
39
+ "[#{casted_values.join(',')}]"
40
+ when Hash
41
+ casted_values = value.map { |k, v| "#{k}: #{value_as_parameter(v)}" }
42
+ "{#{casted_values.join(',')}}"
43
+ else
44
+ scalar_types(value)
45
+ end
46
+ end
47
+
48
+ def scalar_types(value)
49
+ case value
50
+ when TrueClass, FalseClass, Integer, Float
51
+ value
52
+ else # fallback to string
53
+ '"' + value.to_s + '"'
54
+ end
55
+ end
56
+
57
+ def parse_fields(selected_fields)
58
+ results = selected_fields.map do |field|
59
+ case field
60
+ when Hash
61
+ handle_association(field)
62
+ else
63
+ field
64
+ end
65
+ end
66
+
67
+ results.join(' ')
68
+ end
69
+
70
+ def handle_association(hash)
71
+ hash.map do |key, fields|
72
+ "#{key} { #{parse_fields(fields)} }"
73
+ end
74
+ end
75
+
76
+ def query_type
77
+ raise 'query_type undefined'
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module Formatters
5
+ # Class that returns in mutation string format
6
+ class MutationFormat < BaseFormat
7
+ private
8
+
9
+ def query_type
10
+ 'mutation'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module Formatters
5
+ # Class that returns in query string format
6
+ class QueryFormat < BaseFormat
7
+ private
8
+
9
+ def query_type
10
+ 'query'
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ # Wrapper class for HTTParty post query
5
+ class HttpClient
6
+ def initialize(uri, headers)
7
+ @uri = uri
8
+ @headers = headers
9
+ end
10
+
11
+ def query(model, conditions, selected_fields)
12
+ query_string =
13
+ Formatters::QueryFormat.new(model, conditions, selected_fields).create
14
+ parsed_body = raw_query(query_string)
15
+ format_body(parsed_body['data'][model.to_s])
16
+ end
17
+
18
+ def mutation(model, inputs, selected_fields)
19
+ query_string =
20
+ Formatters::MutationFormat.new(model, inputs, selected_fields).create
21
+ parsed_body = raw_query(query_string)
22
+ format_body(parsed_body['data'][model.to_s])
23
+ end
24
+
25
+ def raw_query(query_string, variables: {})
26
+ response = HTTParty.post(@uri,
27
+ headers: @headers,
28
+ body: { query: query_string,
29
+ variables: variables })
30
+ parsed_body = JSON.parse(response.body)
31
+ verify_response!(parsed_body)
32
+ parsed_body
33
+ end
34
+
35
+ private
36
+
37
+ def format_body(response_body)
38
+ return OpenStruct.new(response_body) unless response_body.is_a? Array
39
+
40
+ response_body.map { |entry| OpenStruct.new(entry) }
41
+ end
42
+
43
+ def verify_response!(parsed_body)
44
+ return unless parsed_body.key? 'errors'
45
+
46
+ raise CustomAttributeError, parsed_body['errors']
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module ServiceClassable
5
+ class ClassMethodAlreadyImplementedError < StandardError; end
6
+ class InvalidClassTypeError < StandardError; end
7
+ # Checks whether a class method for a specific graphql query is in an
8
+ # expected format
9
+ class ClassMethodValidator
10
+ class << self
11
+ def validate_class_method(class_method_name, invoked_class)
12
+ return unless invoked_class.singleton_methods
13
+ .map(&:to_s)
14
+ .include?(class_method_name.to_s)
15
+
16
+ error_msg = "The method '#{class_method_name}: ... ' is "\
17
+ 'already implemented within the context of '\
18
+ "#{invoked_class} and therefore cannot be used again!"
19
+ raise ClassMethodAlreadyImplementedError, error_msg
20
+ end
21
+
22
+ def validate_element_class_type(element, class_types)
23
+ return if element.class == class_types
24
+
25
+ raise InvalidClassTypeError, "Please ensure that #{element} is a"\
26
+ "#{class_types}!"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module ServiceClassable
5
+ class InvalidParamsError < StandardError; end
6
+ # Checks whether params for a specifc graphql query are in an expected
7
+ # format
8
+ class ParamsValidator
9
+ class << self
10
+ def validate(query_params)
11
+ params = [query_params].flatten
12
+ return if params.empty? ||
13
+ params.map(&:class).uniq == [Symbol] ||
14
+ params.map(&:class).uniq == [String]
15
+
16
+ raise InvalidParamsError,
17
+ "Please ensure that #{query_params} are either "\
18
+ 'Symbols/Strings as described in the README '\
19
+ '(e.g.: params: [:id, :name])'
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module ServiceClassable
5
+ # Module that allows to build query methods within the context of
6
+ # service class
7
+ module Queryable
8
+ CONDITIONS = 'binding.local_variables.map do |var|
9
+ [var, binding.local_variable_get(var)]
10
+ end.to_h'
11
+
12
+ def add_query(params: [], returns:, **method_to_query)
13
+ class_method_name = method_to_query.first[0]
14
+ query_type = method_to_query.first[1]
15
+ ReturnFieldsValidator.validate(returns)
16
+ ClassMethodValidator.validate_class_method(class_method_name, self)
17
+ ClassMethodValidator.validate_element_class_type(query_type, Symbol)
18
+
19
+ if params.empty?
20
+ return query_method(class_method_name, query_type, returns)
21
+ end
22
+
23
+ ParamsValidator.validate(params)
24
+ query_keyword_method(class_method_name, query_type, params, returns)
25
+ end
26
+
27
+ def add_raw_query(params: [], **method_to_raw_query)
28
+ class_method_name = method_to_raw_query.first[0]
29
+ query_string = method_to_raw_query.first[1]
30
+ ClassMethodValidator.validate_class_method(class_method_name, self)
31
+ ClassMethodValidator.validate_element_class_type(query_string, String)
32
+
33
+ if params.empty?
34
+ return raw_query_method(class_method_name, query_string)
35
+ end
36
+
37
+ ParamsValidator.validate(params)
38
+ raw_query_keyword_method(class_method_name, query_string, params)
39
+ end
40
+
41
+ def add_mutation(params: [], returns:, **method_to_query)
42
+ class_method_name = method_to_query.first[0]
43
+ query_type = method_to_query.first[1]
44
+ ReturnFieldsValidator.validate(returns)
45
+ ClassMethodValidator.validate_class_method(class_method_name, self)
46
+ ClassMethodValidator.validate_element_class_type(query_type, Symbol)
47
+
48
+ if params.empty?
49
+ return mutation_method(class_method_name, query_type, returns)
50
+ end
51
+
52
+ ParamsValidator.validate(params)
53
+ mutation_keyword_method(class_method_name, query_type, params, returns)
54
+ end
55
+
56
+ private
57
+
58
+ def query_method(class_method_name, query_type, return_fields)
59
+ define_singleton_method class_method_name do
60
+ http_client.query(query_type, {}, return_fields.to_a)
61
+ end
62
+ end
63
+
64
+ def raw_query_method(class_method_name, query_string)
65
+ define_singleton_method class_method_name do
66
+ http_client.raw_query(query_string)
67
+ end
68
+ end
69
+
70
+ def query_keyword_method(name, query_type, keywords, return_fields)
71
+ keywords = [keywords].flatten
72
+ instance_eval <<-METHOD, __FILE__, __LINE__ + 1
73
+ def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
74
+ http_client.query("#{query_type}",
75
+ #{CONDITIONS},
76
+ #{return_fields.to_a})
77
+ end
78
+ METHOD
79
+ end
80
+
81
+ def raw_query_keyword_method(name, query_string, keywords)
82
+ keywords = [keywords].flatten
83
+ instance_eval <<-METHOD, __FILE__, __LINE__ + 1
84
+ def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
85
+ http_client.raw_query("#{query_string}", variables: #{CONDITIONS})
86
+ end
87
+ METHOD
88
+ end
89
+
90
+ def mutation_method(class_method_name, query_type, return_fields)
91
+ define_singleton_method class_method_name do
92
+ http_client.mutation(query_type, {}, return_fields.to_a)
93
+ end
94
+ end
95
+
96
+ def mutation_keyword_method(name, query_type, keywords, return_fields)
97
+ keywords = [keywords].flatten
98
+ instance_eval <<-METHOD, __FILE__, __LINE__ + 1
99
+ def #{name}(#{keywords.map { |keyword| "#{keyword}:" }.join(', ')})
100
+ http_client.mutation("#{query_type}",
101
+ #{CONDITIONS},
102
+ #{return_fields.to_a})
103
+ end
104
+ METHOD
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module GraphqlConnector
4
+ module ServiceClassable
5
+ class ReturnFieldsErrors < StandardError; end
6
+ # Valdations for return fields set within the context of a service class
7
+ class ReturnFieldsValidator
8
+ class << self
9
+ def validate(return_fields)
10
+ unless return_fields.is_a?(Array)
11
+ raise ReturnFieldsErrors, 'Please ensure that returns is followed '\
12
+ 'by an array. E.g. returns: [:id]'
13
+ end
14
+
15
+ return_fields.each { |entry| recursive_validation(entry) }
16
+ end
17
+
18
+ private
19
+
20
+ def recursive_validation(entry)
21
+ case entry
22
+ when Hash
23
+ hash_validation(entry)
24
+ when Array
25
+ entry.each { |item| recursive_validation(item) }
26
+ else
27
+ return if [String, Symbol].member?(entry.class)
28
+
29
+ raise ReturnFieldsErrors, "The #{entry} is neither a String nor a"\
30
+ 'Symbol!'
31
+ end
32
+ end
33
+
34
+ def hash_validation(hash)
35
+ hash.each do |key, value|
36
+ recursive_validation(key)
37
+ recursive_validation(value)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GraphqlConnector
4
- VERSION = '0.1.0.beta1'
4
+ VERSION = '1.2.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: graphql_connector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0.beta1
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Garllon
8
+ - sushie1984
8
9
  autorequire:
9
10
  bindir: exe
10
11
  cert_chain: []
11
- date: 2019-10-06 00:00:00.000000000 Z
12
+ date: 2020-12-22 00:00:00.000000000 Z
12
13
  dependencies:
13
14
  - !ruby/object:Gem::Dependency
14
15
  name: httparty
@@ -52,20 +53,6 @@ dependencies:
52
53
  - - "~>"
53
54
  - !ruby/object:Gem::Version
54
55
  version: '0.10'
55
- - !ruby/object:Gem::Dependency
56
- name: rake
57
- requirement: !ruby/object:Gem::Requirement
58
- requirements:
59
- - - "~>"
60
- - !ruby/object:Gem::Version
61
- version: '10.0'
62
- type: :development
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '10.0'
69
56
  - !ruby/object:Gem::Dependency
70
57
  name: rspec
71
58
  requirement: !ruby/object:Gem::Requirement
@@ -94,16 +81,20 @@ dependencies:
94
81
  - - "~>"
95
82
  - !ruby/object:Gem::Version
96
83
  version: '0.75'
97
- description: Hallo
84
+ description: Grahql client to query with your own raw string, with the small helper
85
+ method query or with service class inclusion.
98
86
  email:
99
87
  - palluthe.bennet@gmail.com
88
+ - sascha_burku@yahoo.de
100
89
  executables: []
101
90
  extensions: []
102
91
  extra_rdoc_files: []
103
92
  files:
93
+ - ".github/workflows/ci.yaml"
104
94
  - ".gitignore"
105
95
  - ".rspec"
106
- - ".travis.yml"
96
+ - ".rubocop.yml"
97
+ - ".rubocop_todo.yml"
107
98
  - CHANGELOG.md
108
99
  - CODE_OF_CONDUCT.md
109
100
  - Gemfile
@@ -111,10 +102,23 @@ files:
111
102
  - LICENSE.txt
112
103
  - README.md
113
104
  - bin/console
105
+ - examples/departments_service_class_examples.rb
106
+ - examples/mutation_examples.rb
107
+ - examples/query_examples.rb
108
+ - examples/raw_query_examples.rb
114
109
  - graphql_connector.gemspec
115
110
  - lib/graphql_connector.rb
111
+ - lib/graphql_connector/base_server_type.rb
116
112
  - lib/graphql_connector/configuration.rb
117
- - lib/graphql_connector/query_builder.rb
113
+ - lib/graphql_connector/custom_attribute_error.rb
114
+ - lib/graphql_connector/formatters/base_format.rb
115
+ - lib/graphql_connector/formatters/mutation_format.rb
116
+ - lib/graphql_connector/formatters/query_format.rb
117
+ - lib/graphql_connector/http_client.rb
118
+ - lib/graphql_connector/service_classable/class_method_validator.rb
119
+ - lib/graphql_connector/service_classable/params_validator.rb
120
+ - lib/graphql_connector/service_classable/queryable.rb
121
+ - lib/graphql_connector/service_classable/return_fields_validator.rb
118
122
  - lib/graphql_connector/version.rb
119
123
  homepage: https://github.com/Garllon/graphql_connector/blob/master/README.md
120
124
  licenses:
@@ -134,12 +138,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
134
138
  version: '0'
135
139
  required_rubygems_version: !ruby/object:Gem::Requirement
136
140
  requirements:
137
- - - ">"
141
+ - - ">="
138
142
  - !ruby/object:Gem::Version
139
- version: 1.3.1
143
+ version: '0'
140
144
  requirements: []
141
- rubygems_version: 3.0.6
145
+ rubygems_version: 3.0.4
142
146
  signing_key:
143
147
  specification_version: 4
144
- summary: Hallo
148
+ summary: GraphQL client
145
149
  test_files: []
@@ -1,9 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.4
7
- before_install: gem install bundler -v 2.0.2
8
- script:
9
- - bundle exec rspec spec
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module GraphqlConnector
4
- class QueryBuilder
5
- def initialize(model, conditions, selected_fields)
6
- @model = model
7
- @conditions = conditions
8
- @selected_fields = selected_fields
9
- end
10
-
11
- def create
12
- "query { #{@model}(#{main_filter}) { #{@selected_fields.join(' ')} } }"
13
- end
14
-
15
- private
16
-
17
- def main_filter
18
- conditions = @conditions.each_with_object([]) do |(key, value), array|
19
- next if value.is_a? Hash # will be processed in #field_with_filter
20
-
21
- array << "#{key}: #{value_as_parameter(value)}"
22
- end
23
-
24
- conditions.join(', ')
25
- end
26
-
27
- def value_as_parameter(value)
28
- case value
29
- when TrueClass, FalseClass, Integer, Float
30
- value
31
- when Array
32
- casted_values = value.map { |v| value_as_parameter(v) }
33
- "[#{casted_values.join(',')}]"
34
- else # fallback to string
35
- '"' + value.to_s + '"'
36
- end
37
- end
38
- end
39
- end