Skip to content

Commit 4358496

Browse files
committed
initial commit
0 parents  commit 4358496

File tree

14 files changed

+279
-0
lines changed

14 files changed

+279
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.gem

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 Alex Sharp
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
# graphql-rails-generators
2+
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+
5+
This project contains three generators that look at your ActiveRecord model schema and generates graphql types for you.
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
10+
11+
## Installation
12+
13+
```
14+
gem 'graphql-rails-generators', group: :development
15+
```
16+
17+
## Requirements
18+
19+
This library only supports ActiveRecord, though it would be fairly trivial to add support for other ORMs.
20+
21+
## Usage
22+
23+
### gql:model_type
24+
25+
Generate a model type from a model.
26+
27+
```
28+
$ rails generate gql:model_type MODEL_CLASS
29+
```
30+
31+
Result:
32+
33+
```ruby
34+
# app/graphql/post_type.rb
35+
module Types
36+
class PostType < Types::BaseObject
37+
field :id, Int, null: true
38+
field :title, String, null: true
39+
field :body, String, null: true
40+
field :created_at, GraphQL::Types::ISO8601DateTime, null: true
41+
field :updated_at, GraphQL::Types::ISO8601DateTime, null: true
42+
end
43+
end
44+
```
45+
46+
### gql:input MODEL_CLASS
47+
48+
Generate an input type from a model.
49+
50+
```
51+
rails generate gql:input Post
52+
```
53+
54+
Result:
55+
```ruby
56+
# app/graphql/types/post_input.rb
57+
module Types
58+
module Input
59+
class PostInput < Types::BaseInputObject
60+
argument :title, String, required: false
61+
argument :body, String, required: false
62+
end
63+
end
64+
end
65+
```
66+
67+
### gql:mutation MUTATION_PREFIX MODEL_NAME
68+
69+
Generate a mutation class from a model.
70+
71+
A quick note about the mutation generator...
72+
73+
The mutation generator generates something akin to an "upsert" mutation. It takes two arguments: an optional `id` and an optional `attributes`, which is the input type for the model. If you pass an `id`, it will attempt to find the model by the `id` and update it, otherwise it will initialize a new model and attempt to save it.
74+
75+
```
76+
rails generate gql:mutation Update Post
77+
```
78+
79+
Result:
80+
```ruby
81+
# app/graphql/mutations/update_post.rb
82+
module Mutations
83+
class UpdatePost < Mutations::BaseMutation
84+
field :post, Types::PostType, null: true
85+
86+
argument :attributes, Types::Input::PostInput, required: true
87+
argument :id, Int, required: false
88+
89+
def resolve(attributes:, id: nil)
90+
model = find_or_build_model(id)
91+
model.attributes = attributes.to_h
92+
if model.save
93+
{post: model}
94+
else
95+
{errors: model.errors.full_messages}
96+
end
97+
end
98+
99+
def find_or_build_model(id)
100+
if id
101+
Post.find(id)
102+
else
103+
Post.new
104+
end
105+
end
106+
end
107+
end
108+
```

Rakefile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
gemspec = eval(File.read("graphql-rails-generators.gemspec"))
2+
3+
task :build => "#{gemspec.full_name}.gem"
4+
5+
file "#{gemspec.full_name}.gem" => gemspec.files + ["graphql-rails-generators.gemspec"] do
6+
system "gem build graphql-rails-generators.gemspec"
7+
system "git tag v#{GraphqlRailsGenerators::VERSION}"
8+
end

graphql-rails-generators.gemspec

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
require File.expand_path("../lib/graphql-rails-generators/version", __FILE__)
2+
Gem::Specification.new do |s|
3+
s.name = 'graphql-rails-generators'
4+
s.version = GraphqlRailsGenerators::VERSION
5+
s.platform = Gem::Platform::RUBY
6+
s.date = '2019-11-26'
7+
s.summary = "Hola!"
8+
s.description = "A simple hello world gem"
9+
s.authors = ["Alex Sharp"]
10+
s.email = '[email protected]'
11+
s.files = Dir["{lib}/**/*.rb", "LICENSE", "*.md"]
12+
s.require_path = 'lib'
13+
s.homepage = 'https://github.com/ajsharp/graphql-rails-generators'
14+
s.license = 'MIT'
15+
end

lib/generators/gql/USAGE

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Description:
2+
Generate GraphQL types, mutations, and input types from your rails models.
3+
4+
Example:
5+
rails generate gql:model_type model_type
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
require 'rails/generators/base'
2+
# require 'active_support/extend'
3+
module Gql
4+
module GqlGeneratorBase
5+
extend ActiveSupport::Concern
6+
7+
included do
8+
protected
9+
def type_map
10+
{
11+
integer: 'Int',
12+
string: 'String',
13+
boolean: 'Boolean',
14+
decimal: 'Float',
15+
datetime: 'GraphQL::Types::ISO8601DateTime',
16+
date: 'GraphQL::Types::ISO8601Date',
17+
hstore: 'GraphQL::Types::JSON'
18+
}
19+
end
20+
21+
def map_model_types(model_name)
22+
klass = model_name.constantize
23+
associations = klass.reflect_on_all_associations(:belongs_to)
24+
bt_columns = associations.map(&:foreign_key)
25+
26+
klass.columns
27+
.reject { |col| bt_columns.include?(col.name) }
28+
.map { |col| {name: col.name, gql_type: type_map.fetch(col.type)} }
29+
end
30+
end
31+
end
32+
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
require_relative 'gql_generator_base'
2+
module Gql
3+
class InputGenerator < Rails::Generators::Base
4+
include GqlGeneratorBase
5+
source_root File.expand_path('../templates', __FILE__)
6+
argument :model_name, type: :string
7+
8+
def generate_input_type
9+
file_name = model_name
10+
11+
ignore = ['id', 'created_at', 'updated_at']
12+
@fields = map_model_types(model_name).reject { |field| ignore.include?(field[:name]) }
13+
14+
template('input_type.rb', "app/graphql/types/input/#{file_name.underscore}_input.rb")
15+
end
16+
end
17+
end
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
require_relative 'gql_generator_base'
2+
module Gql
3+
class ModelTypeGenerator < Rails::Generators::Base
4+
include GqlGeneratorBase
5+
source_root File.expand_path('../templates', __FILE__)
6+
argument :model_name, type: :string
7+
8+
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")
12+
end
13+
end
14+
end
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
module Gql
2+
class MutationGenerator < Rails::Generators::Base
3+
argument :mutation_prefix, type: :string
4+
argument :model_name, type: :string
5+
source_root File.expand_path('../templates', __FILE__)
6+
7+
def mutation
8+
file_name = "#{mutation_prefix}#{model_name}"
9+
template('model_mutation.rb', "app/graphql/mutations/#{file_name.underscore}.rb")
10+
end
11+
end
12+
13+
end

0 commit comments

Comments
 (0)