search_object_graphql 0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.projections.json +8 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +39 -0
  6. data/.travis.yml +11 -0
  7. data/CHANGELOG.md +5 -0
  8. data/Gemfile +4 -0
  9. data/LICENSE.txt +22 -0
  10. data/README.md +194 -0
  11. data/Rakefile +8 -0
  12. data/example/.gitignore +20 -0
  13. data/example/.ruby-version +1 -0
  14. data/example/Gemfile +22 -0
  15. data/example/README.md +83 -0
  16. data/example/Rakefile +6 -0
  17. data/example/app/controllers/application_controller.rb +2 -0
  18. data/example/app/controllers/graphql_controller.rb +29 -0
  19. data/example/app/graphql/resolvers/base_search_resolver.rb +9 -0
  20. data/example/app/graphql/resolvers/category_search.rb +35 -0
  21. data/example/app/graphql/resolvers/post_search.rb +69 -0
  22. data/example/app/graphql/schema.rb +3 -0
  23. data/example/app/graphql/types/.keep +0 -0
  24. data/example/app/graphql/types/category_type.rb +8 -0
  25. data/example/app/graphql/types/date_time_type.rb +6 -0
  26. data/example/app/graphql/types/post_type.rb +13 -0
  27. data/example/app/graphql/types/query_type.rb +7 -0
  28. data/example/app/models/application_record.rb +3 -0
  29. data/example/app/models/category.rb +5 -0
  30. data/example/app/models/post.rb +14 -0
  31. data/example/bin/bundle +3 -0
  32. data/example/bin/rails +4 -0
  33. data/example/bin/rake +4 -0
  34. data/example/bin/setup +34 -0
  35. data/example/bin/update +29 -0
  36. data/example/config.ru +5 -0
  37. data/example/config/application.rb +36 -0
  38. data/example/config/boot.rb +3 -0
  39. data/example/config/cable.yml +10 -0
  40. data/example/config/database.yml +25 -0
  41. data/example/config/environment.rb +5 -0
  42. data/example/config/environments/development.rb +42 -0
  43. data/example/config/environments/production.rb +78 -0
  44. data/example/config/environments/test.rb +36 -0
  45. data/example/config/initializers/wrap_parameters.rb +14 -0
  46. data/example/config/puma.rb +56 -0
  47. data/example/config/routes.rb +5 -0
  48. data/example/config/secrets.yml +32 -0
  49. data/example/config/spring.rb +6 -0
  50. data/example/db/migrate/20170507175133_create_demo_tables.rb +21 -0
  51. data/example/db/schema.rb +36 -0
  52. data/example/db/seeds.rb +35 -0
  53. data/example/log/.keep +0 -0
  54. data/example/public/robots.txt +1 -0
  55. data/example/vendor/.keep +0 -0
  56. data/lib/search_object/plugin/graphql.rb +84 -0
  57. data/lib/search_object/plugin/graphql/version.rb +7 -0
  58. data/search_object_graphql.gemspec +31 -0
  59. data/spec/search_object/plugin/graphql_spec.rb +288 -0
  60. data/spec/spec_helper.rb +12 -0
  61. data/spec/spec_helper_active_record.rb +29 -0
  62. metadata +219 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 20d420d2ee1dd08bdfe48da2c5e1e3ba0a3a8233
4
+ data.tar.gz: 57a5009d415d6fad948001d18d428676dbd1471c
5
+ SHA512:
6
+ metadata.gz: d25a679fad52b5605c5720a774f2bee6d273abc369dbfd90cc48a75793d7fd3cc6359092406d178aecd0ae97fdb6e2f938f891b764b2ebfb26c47bf99fc63605
7
+ data.tar.gz: f7d5f5e368c50e3bc274b8d665c83ca975f1093e55a7059c906f17e93a40388c097d51ce7288b99394b3d8268913bfe0ea1ef1d2a611bedaa0e7df9380160f5f
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,8 @@
1
+ {
2
+ "lib/*.rb": {
3
+ "alternate": "spec/{}_spec.rb"
4
+ },
5
+ "spec/*_spec.rb": {
6
+ "alternate": "lib/{}.rb"
7
+ },
8
+ }
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --colour
2
+ --format=documentation
@@ -0,0 +1,39 @@
1
+ require: rubocop-rspec
2
+
3
+ AllCops:
4
+ Exclude:
5
+ - example/db/**/*
6
+ - example/config/**/*
7
+ - search_object.gemspec
8
+
9
+ # Disables "Line is too long"
10
+ LineLength:
11
+ Enabled: false
12
+
13
+ # Disables Module has too many lines
14
+ ModuleLength:
15
+ Enabled: false
16
+
17
+ # Disables "Missing top-level class documentation comment"
18
+ Documentation:
19
+ Enabled: false
20
+
21
+ # Disables "Use each_with_object instead of inject"
22
+ Style/EachWithObject:
23
+ Enabled: false
24
+
25
+ # Disables "Prefer reduce over inject."
26
+ Style/CollectionMethods:
27
+ Enabled: false
28
+
29
+ # Disables "Block has too many lines."
30
+ Metrics/BlockLength:
31
+ Enabled: false
32
+
33
+ # Disables "Example has too many lines."
34
+ RSpec/ExampleLength:
35
+ Enabled: false
36
+
37
+ # Disables "Too many expectations."
38
+ RSpec/MultipleExpectations:
39
+ Enabled: false
@@ -0,0 +1,11 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.2
4
+ - 2.3.0
5
+ script:
6
+ - bundle exec rubocop
7
+ - bundle exec rspec spec
8
+ notifications:
9
+ email: false
10
+ before_install:
11
+ - gem install bundler
@@ -0,0 +1,5 @@
1
+ # Changelog
2
+
3
+ ## Version 0.1
4
+
5
+ * Initial release (@rstankov)
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in search_object.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2017 Radoslav Stankov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,194 @@
1
+ [![Code Climate](https://codeclimate.com/github/RStankov/SearchObjectGraphQL.svg)](https://codeclimate.com/github/RStankov/SearchObjectGraphQL)
2
+ [![Build Status](https://secure.travis-ci.org/RStankov/SearchObjectGraphQL.svg)](http://travis-ci.org/RStankov/SearchObjectGraphQL)
3
+ [![Code coverage](https://coveralls.io/repos/RStankov/SearchObjectGraphQL/badge.svg?branch=master#2)](https://coveralls.io/r/RStankov/SearchObjectGraphQL)
4
+
5
+ # SearchObject::Plugin::GraphQL
6
+
7
+ [SearchObject](https://github.com/RStankov/SearchObject) plugin for [GraphQL Ruby](https://rmosolgo.github.io/graphql-ruby/).
8
+
9
+ ## Table of Contents
10
+
11
+ * [Installation](#installation)
12
+ * [Dependencies](#dependencies)
13
+ * [Usage](#usage)
14
+ * [Example](#example)
15
+ * [Features](#features)
16
+ * [Custom Types](#custom-types)
17
+ * [Documentation](#documentation)
18
+ * [Default Values](#default-values)
19
+ * [Accessing Parent Object](#accessing-parent-object)
20
+ * [Enums Support](#enums-support)
21
+ * [Relay Support](#relay-support)
22
+
23
+ ## Installation
24
+
25
+ Add this line to your application's Gemfile:
26
+
27
+ ```ruby
28
+ gem 'search_object'
29
+ ```
30
+
31
+ And then execute:
32
+
33
+ $ bundle
34
+
35
+ Or install it yourself as:
36
+
37
+ $ gem install search_object
38
+
39
+ ## Dependencies
40
+
41
+ - `SearchObject` >= 1.2
42
+ - `Graphql` >= 1.5
43
+
44
+ ## Usage
45
+
46
+ Just include the ```SearchObject.module``` and define your search options and their types:
47
+
48
+ ```ruby
49
+ class PostResolver
50
+ include SearchObject.module(:graphql)
51
+
52
+ type PostType
53
+
54
+ scope { Post.all }
55
+
56
+ option(:name, type: types.String) { |scope, value| scope.where name: value }
57
+ option(:published, type: types.Boolean) { |scope, value| value ? scope.published : scope.unpublished }
58
+ end
59
+ ```
60
+
61
+ Then you can just use `PostResolver` as [GraphQL::Function](https://rmosolgo.github.io/graphql-ruby/schema/code_reuse#functions):
62
+
63
+ ```ruby
64
+ field :posts, function: PostResolver
65
+ ```
66
+
67
+ Options are exposed as arguments in the GraphQL query:
68
+
69
+ ```
70
+ posts(name: 'Example') { ... }
71
+ posts(published: true) { ... }
72
+ posts(published: true, name: 'Example') { ... }
73
+ ```
74
+
75
+ ### Example
76
+
77
+ You can find example of most important features and plugins - [here](https://github.com/RStankov/SearchObjectGraphQL/tree/master/example).
78
+
79
+ ## Features
80
+
81
+ ### Custom Types
82
+
83
+ Custom types can be define inside the search object:
84
+
85
+ ```ruby
86
+ class PostResolver
87
+ include SearchObject.module(:graphql)
88
+
89
+ type do
90
+ name 'Custom Type'
91
+
92
+ field :id, !types.ID
93
+ field :title, !types.String
94
+ field :body, !types.String
95
+ end
96
+
97
+ # ...
98
+ end
99
+ ```
100
+
101
+ ### Documentation
102
+
103
+ Search object itself can be documented, as well as its options:
104
+
105
+ ```ruby
106
+ class PostResolver
107
+ include SearchObject.module(:graphql)
108
+
109
+ description 'Lists all posts'
110
+
111
+ option(:name, type: types.String, description: 'Fuzzy name matching') { ... }
112
+ option(:published, type: types.Boolean, description: 'Find published/unpublished') { ... }
113
+ end
114
+ ```
115
+
116
+ ### Default Values
117
+
118
+ ```ruby
119
+ class PostResolver
120
+ include SearchObject.module(:graphql)
121
+
122
+ scope { Post.all }
123
+
124
+ option(:published, type: types.Boolean, default: true) { |scope, value| value ? scope.published : scope.unpublished }
125
+ end
126
+ ```
127
+
128
+ ### Accessing Parent Object
129
+
130
+ Sometimes you want to scope posts based on parent object, it is accessible as `object` property:
131
+
132
+ ```ruby
133
+ class PostResolver
134
+ include SearchObject.module(:graphql)
135
+
136
+ # lists only posts from certain category
137
+ scope { object.posts }
138
+
139
+ # ...
140
+ end
141
+ ```
142
+
143
+ If you need GraphQL context, it is accessible as `context`.
144
+
145
+ ### Enums Support
146
+
147
+ ```ruby
148
+ class PostSearch
149
+ include SearchObject.module(:graphql)
150
+
151
+ OrderEnum = GraphQL::EnumType.define do
152
+ name 'PostOrder'
153
+
154
+ value 'RECENT'
155
+ value 'VIEWS'
156
+ value 'COMMENTS'
157
+ end
158
+
159
+ option :order, type: OrderEnum, default: 'RECENT'
160
+
161
+ def apply_order_with_recent(scope)
162
+ scope.order 'created_at DESC'
163
+ end
164
+
165
+ def apply_order_with_views(scope)
166
+ scope.order 'views_count DESC'
167
+ end
168
+
169
+ def apply_order_with_comments(scope)
170
+ scope.order 'comments_count DESC'
171
+ end
172
+ end
173
+ ```
174
+
175
+ ### Relay Support
176
+
177
+ Search objects can be used as [Relay Connections](https://rmosolgo.github.io/graphql-ruby/relay/connections):
178
+
179
+ ```ruby
180
+ connection :posts, Types::PostType.connection_type, function: Resolvers::PostSearch
181
+ ```
182
+
183
+ ## Contributing
184
+
185
+ 1. Fork it
186
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
187
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
188
+ 4. Push to the branch (`git push origin my-new-feature`)
189
+ 5. Run the tests (`rake`)
190
+ 6. Create new Pull Request
191
+
192
+ ## License
193
+
194
+ **[MIT License](https://github.com/RStankov/SearchObjectGraphQL/blob/master/LICENSE.txt)**
@@ -0,0 +1,8 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubocop/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ RuboCop::RakeTask.new(:rubocop)
7
+
8
+ task default: [:rubocop, :spec]
@@ -0,0 +1,20 @@
1
+ # See https://help.github.com/articles/ignoring-files for more about ignoring files.
2
+ #
3
+ # If you find yourself ignoring temporary files generated by your text editor
4
+ # or operating system, you probably want to add a global ignore instead:
5
+ # git config --global core.excludesfile '~/.gitignore_global'
6
+
7
+ # Ignore bundler config.
8
+ /.bundle
9
+
10
+ # Ignore the default SQLite database.
11
+ /db/*.sqlite3
12
+ /db/*.sqlite3-journal
13
+
14
+ # Ignore all logfiles and tempfiles.
15
+ /log/*
16
+ /tmp/*
17
+ !/log/.keep
18
+ !/tmp/.keep
19
+
20
+ .byebug_history
@@ -0,0 +1 @@
1
+ 2.3.1
@@ -0,0 +1,22 @@
1
+ source 'https://rubygems.org'
2
+
3
+ git_source(:github) do |repo_name|
4
+ repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?('/')
5
+ "https://github.com/#{repo_name}.git"
6
+ end
7
+
8
+ gem 'rails', '~> 5.1.0'
9
+
10
+ gem 'graphql'
11
+ gem 'puma', '~> 3.7'
12
+ gem 'search_object'
13
+ gem 'sqlite3'
14
+
15
+ group :development do
16
+ gem 'listen', '>= 3.0.5', '< 3.2'
17
+ # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
18
+ gem 'spring'
19
+ gem 'spring-watcher-listen', '~> 2.0.0'
20
+ end
21
+
22
+ gem 'graphiql-rails', group: :development
@@ -0,0 +1,83 @@
1
+ # SearchObject::Plugin::Graphql Example Rails Application
2
+
3
+ This is example application showing, one of the possible usages of ```SearchObject::Plugin::Graphql```.
4
+
5
+ ## Interesting Files:
6
+
7
+ * [Types::QueryType](https://github.com/RStankov/SearchObjectGraphQL/blob/master/example/app/graphql/types/query_type.rb)
8
+ * [Types::CategoryType](https://github.com/RStankov/SearchObjectGraphQL/blob/master/example/app/graphql/types/category_type.rb)
9
+ * [Types::PostType](https://github.com/RStankov/SearchObjectGraphQL/blob/master/example/app/graphql/types/post_type.rb)
10
+ * [Resolvers::BaseSearchResolver](https://github.com/RStankov/SearchObjectGraphQL/blob/master/example/app/graphql/resolvers/base_search_resolver.rb)
11
+ * [Resolvers::CategoryResolver](https://github.com/RStankov/SearchObjectGraphQL/blob/master/example/app/graphql/resolvers/category_search.rb)
12
+ * [Resolvers::PostResolver](https://github.com/RStankov/SearchObjectGraphQL/blob/master/example/app/graphql/resolvers/post_search.rb)
13
+
14
+ ## Installation
15
+
16
+ ```
17
+ gem install bundler
18
+ bundle install
19
+ rake db:create
20
+ rake db:migrate
21
+ rake db:seed
22
+
23
+ rails server
24
+ ```
25
+
26
+ From there just visit: [localhost:3000/](http://localhost:3000/). This would open [graphiql](https://github.com/graphql/graphiql).
27
+
28
+ ## Sample GraphQL Queries
29
+
30
+ ```
31
+ {
32
+ categories {
33
+ edges {
34
+ node {
35
+ id
36
+ name
37
+ posts(published: false) {
38
+ edges {
39
+ node {
40
+ id
41
+ title
42
+ }
43
+ }
44
+ }
45
+ }
46
+ }
47
+ }
48
+ }
49
+ ```
50
+
51
+ ```graphql
52
+ {
53
+ posts(first: 10, published: true, order: VIEWS) {
54
+ edges {
55
+ node {
56
+ title
57
+ isPublished
58
+ viewsCount
59
+ publishedAt
60
+ }
61
+ }
62
+ }
63
+ }
64
+ ```
65
+
66
+ ```graphql
67
+ {
68
+ posts(first: 10, title: "Example", order: VIEWS) {
69
+ edges {
70
+ node {
71
+ title
72
+ category {
73
+ id
74
+ name
75
+ }
76
+ isPublished
77
+ viewsCount
78
+ publishedAt
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```