Skip to content

Commit cb7a04d

Browse files
authored
Merge pull request #34 from richmolj/master
Enhance generators with comments
2 parents 924ae0d + 7e9d314 commit cb7a04d

File tree

7 files changed

+280
-61
lines changed

7 files changed

+280
-61
lines changed

lib/generators/jsonapi/resource_generator.rb

Lines changed: 139 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -2,85 +2,166 @@ module Jsonapi
22
class ResourceGenerator < ::Rails::Generators::NamedBase
33
source_root File.expand_path('../templates', __FILE__)
44

5-
class_option :'no-controller', type: :boolean, default: false
6-
class_option :'no-serializer', type: :boolean, default: false
7-
class_option :'no-payload', type: :boolean, default: false
8-
class_option :'no-strong-resources', type: :boolean, default: false
9-
class_option :'no-test', type: :boolean, default: false
10-
11-
desc "This generator creates a resource file at app/resources"
5+
class_option :'omit-comments',
6+
type: :boolean,
7+
default: false,
8+
aliases: ['--omit-comments', '-c'],
9+
desc: 'Generate without documentation comments'
10+
class_option :'omit-controller',
11+
type: :boolean,
12+
default: false,
13+
aliases: ['--omit-controller'],
14+
desc: 'Generate without controller'
15+
class_option :'omit-serializer',
16+
type: :boolean,
17+
default: false,
18+
aliases: ['--omit-serializer', '-s'],
19+
desc: 'Generate without serializer'
20+
class_option :'omit-payload',
21+
type: :boolean,
22+
default: false,
23+
aliases: ['--omit-payload', '-p'],
24+
desc: 'Generate without spec payload'
25+
class_option :'omit-strong-resource',
26+
type: :boolean,
27+
default: false,
28+
aliases: ['--omit-strong-resource', '-r'],
29+
desc: 'Generate without strong resource'
30+
class_option :'omit-route',
31+
type: :boolean,
32+
default: false,
33+
aliases: ['--omit-route'],
34+
desc: 'Generate without specs'
35+
class_option :'omit-tests',
36+
type: :boolean,
37+
default: false,
38+
aliases: ['--omit-tests', '-t'],
39+
desc: 'Generate without specs'
40+
41+
desc "This generator creates a resource file at app/resources, as well as corresponding controller/specs/route/etc"
1242
def copy_resource_file
13-
unless @options['no-controller']
14-
to = File.join('app/controllers', class_path, "#{file_name.pluralize}_controller.rb")
15-
template('controller.rb.erb', to)
43+
unless model_klass
44+
raise "You must define a #{class_name} model before generating the corresponding resource."
1645
end
1746

18-
unless @options['no-serializer']
19-
to = File.join('app/serializers', class_path, "serializable_#{file_name}.rb")
20-
template('serializer.rb.erb', to)
21-
end
47+
generate_controller unless omit_controller?
48+
generate_serializer unless omit_serializer?
49+
generate_application_resource unless application_resource_defined?
50+
generate_spec_payload unless omit_spec_payload?
51+
generate_strong_resource unless omit_strong_resource?
52+
generate_route unless omit_route?
53+
generate_tests unless omit_tests?
54+
generate_resource
55+
end
2256

23-
unless 'ApplicationResource'.safe_constantize
24-
to = File.join('app/resources', class_path, "application_resource.rb")
25-
template('application_resource.rb.erb', to)
26-
end
57+
private
2758

28-
unless @options['no-payload']
29-
to = File.join('spec/payloads', class_path, "#{file_name}.rb")
30-
template('payload.rb.erb', to)
31-
end
59+
def omit_comments?
60+
@options['omit-comments']
61+
end
62+
63+
def generate_controller
64+
to = File.join('app/controllers', class_path, "#{file_name.pluralize}_controller.rb")
65+
template('controller.rb.erb', to)
66+
end
3267

33-
unless @options['no-strong-resources']
34-
inject_into_file 'config/initializers/strong_resources.rb', after: "StrongResources.configure do\n" do <<-STR
68+
def omit_controller?
69+
@options['omit-controller']
70+
end
71+
72+
def generate_serializer
73+
to = File.join('app/serializers', class_path, "serializable_#{file_name}.rb")
74+
template('serializer.rb.erb', to)
75+
end
76+
77+
def omit_serializer?
78+
@options['omit-serializer']
79+
end
80+
81+
def generate_application_resource
82+
to = File.join('app/resources', class_path, "application_resource.rb")
83+
template('application_resource.rb.erb', to)
84+
end
85+
86+
def application_resource_defined?
87+
'ApplicationResource'.safe_constantize.present?
88+
end
89+
90+
def generate_spec_payload
91+
to = File.join('spec/payloads', class_path, "#{file_name}.rb")
92+
template('payload.rb.erb', to)
93+
end
94+
95+
def omit_spec_payload?
96+
@options['no-payload']
97+
end
98+
99+
def generate_strong_resource
100+
code = <<-STR
35101
strong_resource :#{file_name} do
36102
# Your attributes go here, e.g.
37103
# attribute :name, :string
38104
end
39105
40-
STR
41-
end
106+
STR
107+
inject_into_file 'config/initializers/strong_resources.rb', after: "StrongResources.configure do\n" do
108+
code
42109
end
110+
end
111+
112+
def omit_strong_resource?
113+
@options['no-strong-resources']
114+
end
43115

44-
unless @options['no-route']
45-
inject_into_file 'config/routes.rb', after: "scope '/api' do\n scope '/v1' do\n" do <<-STR
116+
def generate_route
117+
code = <<-STR
46118
resources :#{type}
47-
STR
48-
end
119+
STR
120+
inject_into_file 'config/routes.rb', after: "scope path: '/api' do\n scope path: '/v1' do\n" do
121+
code
49122
end
123+
end
50124

51-
unless @options['no-test']
52-
to = File.join "spec/api/v1/#{file_name.pluralize}",
53-
class_path,
54-
"index_spec.rb"
55-
template('index_request_spec.rb.erb', to)
56-
57-
to = File.join "spec/api/v1/#{file_name.pluralize}",
58-
class_path,
59-
"show_spec.rb"
60-
template('show_request_spec.rb.erb', to)
61-
62-
to = File.join "spec/api/v1/#{file_name.pluralize}",
63-
class_path,
64-
"create_spec.rb"
65-
template('create_request_spec.rb.erb', to)
66-
67-
to = File.join "spec/api/v1/#{file_name.pluralize}",
68-
class_path,
69-
"update_spec.rb"
70-
template('update_request_spec.rb.erb', to)
71-
72-
to = File.join "spec/api/v1/#{file_name.pluralize}",
73-
class_path,
74-
"destroy_spec.rb"
75-
template('destroy_request_spec.rb.erb', to)
76-
end
125+
def omit_route?
126+
@options['no-route']
127+
end
128+
129+
def generate_tests
130+
to = File.join "spec/api/v1/#{file_name.pluralize}",
131+
class_path,
132+
"index_spec.rb"
133+
template('index_request_spec.rb.erb', to)
134+
135+
to = File.join "spec/api/v1/#{file_name.pluralize}",
136+
class_path,
137+
"show_spec.rb"
138+
template('show_request_spec.rb.erb', to)
139+
140+
to = File.join "spec/api/v1/#{file_name.pluralize}",
141+
class_path,
142+
"create_spec.rb"
143+
template('create_request_spec.rb.erb', to)
144+
145+
to = File.join "spec/api/v1/#{file_name.pluralize}",
146+
class_path,
147+
"update_spec.rb"
148+
template('update_request_spec.rb.erb', to)
149+
150+
to = File.join "spec/api/v1/#{file_name.pluralize}",
151+
class_path,
152+
"destroy_spec.rb"
153+
template('destroy_request_spec.rb.erb', to)
154+
end
77155

156+
def omit_tests?
157+
@options['no-test']
158+
end
159+
160+
def generate_resource
78161
to = File.join('app/resources', class_path, "#{file_name}_resource.rb")
79162
template('resource.rb.erb', to)
80163
end
81164

82-
private
83-
84165
def model_klass
85166
class_name.safe_constantize
86167
end
Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,14 @@
1-
require 'jsonapi_compliable/adapters/active_record'
2-
1+
<%- unless omit_comments? -%>
2+
# ApplicationResource is similar to ApplicationRecord - a base class that
3+
# holds configuration/methods for subclasses.
4+
# All Resources should inherit from ApplicationResource.
5+
# Resource documentation: https://jsonapi-suite.github.io/jsonapi_compliable/JsonapiCompliable/Resource.html
6+
<%- end -%>
37
class ApplicationResource < JsonapiCompliable::Resource
8+
<%- unless omit_comments? -%>
9+
# Use the ActiveRecord Adapter for all subclasses.
10+
# Subclasses can still override this default.
11+
# More on adapters: https://jsonapi-suite.github.io/jsonapi_compliable/JsonapiCompliable/Adapters/Abstract.html
12+
<%- end -%>
413
use_adapter JsonapiCompliable::Adapters::ActiveRecord
514
end

lib/generators/jsonapi/templates/controller.rb.erb

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,46 @@
11
<% module_namespacing do -%>
22
class <%= model_klass.name.pluralize %>Controller < ApplicationController
3+
<%- unless omit_comments? -%>
4+
# Mark this as a JSONAPI controller, associating with the given resource
5+
<%- end -%>
36
jsonapi resource: <%= model_klass %>Resource
47

8+
<%- unless omit_comments? -%>
9+
# Reference a strong resource payload defined in
10+
# config/initializers/strong_resources.rb
11+
<%- end -%>
512
strong_resource :<%= file_name %>
613

14+
<%- unless omit_comments? -%>
15+
# Run strong parameter validation for these actions.
16+
# Invalid keys will be dropped.
17+
# Invalid value types will log or raise based on the configuration
18+
# ActionController::Parameters.action_on_invalid_parameters
19+
<%- end -%>
720
before_action :apply_strong_params, only: [:create, :update]
821

22+
<%- unless omit_comments? -%>
23+
# Start with a base scope and pass to render_jsonapi
24+
<%- end -%>
925
def index
1026
<%= file_name.pluralize %> = <%= model_klass %>.all
1127
render_jsonapi(<%= file_name.pluralize %>)
1228
end
1329

30+
<%- unless omit_comments? -%>
31+
# Call jsonapi_scope directly here so we can get behavior like
32+
# sparse fieldsets and statistics.
33+
<%- end -%>
1434
def show
1535
scope = jsonapi_scope(<%= model_klass %>.where(id: params[:id]))
1636
render_jsonapi(scope.resolve.first, scope: false)
1737
end
1838

39+
<%- unless omit_comments? -%>
40+
# jsonapi_create will use the configured Resource (and adapter) to persist.
41+
# This will handle nested relationships as well.
42+
# On validation errors, render correct error JSON.
43+
<%- end -%>
1944
def create
2045
<%= file_name %>, success = jsonapi_create.to_a
2146

@@ -26,6 +51,11 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
2651
end
2752
end
2853

54+
<%- unless omit_comments? -%>
55+
# jsonapi_update will use the configured Resource (and adapter) to persist.
56+
# This will handle nested relationships as well.
57+
# On validation errors, render correct error JSON.
58+
<%- end -%>
2959
def update
3060
<%= file_name %>, success = jsonapi_update.to_a
3161

@@ -36,6 +66,10 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
3666
end
3767
end
3868

69+
<%- unless omit_comments? -%>
70+
# No need for any special logic here as no_content is jsonapi_compliant.
71+
# Customize this if you have a more complex use case.
72+
<%- end -%>
3973
def destroy
4074
<%= file_name %> = <%= model_klass %>.find(params[:id])
4175
<%= file_name %>.destroy

lib/generators/jsonapi/templates/destroy_request_spec.rb.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ require 'rails_helper'
22

33
RSpec.describe "<%= type %>#destroy", type: :request do
44
context 'basic destroy' do
5-
let!(:<%= file_name %>) { create(:<%= file_name %>) }
5+
let!(:<%= file_name %>) { FactoryGirl.create(:<%= file_name %>) }
66

77
it 'updates the resource' do
88
expect {
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,33 @@
1+
<%- unless omit_comments? -%>
2+
# Register a payload to validate against.
3+
# Add expected attributes within this block, e.g.:
4+
#
5+
# key(:name)
6+
#
7+
# Optionally validate the type as well:
8+
#
9+
# key(:name, String)
10+
#
11+
# This will:
12+
#
13+
# * Compare record.name == json['name']
14+
# * Ensure no extra keys are in the json payload
15+
# * Ensure no values are nil (unless allow_nil: true is passed)
16+
# * Ensures json['name'] is a string
17+
#
18+
# If you have custom serialization logic and want to compare against
19+
# something other than "record.name", pass a block:
20+
#
21+
# key(:name) { |record| record.name.upcase }
22+
#
23+
# Or, if this is a one-off for a particular spec, do that customization at
24+
# runtime:
25+
#
26+
# assert_payload(:person, person_record, json_item) do
27+
# key(:name) { 'Homer Simpson' }
28+
# end
29+
#
30+
# For more information, see https://jsonapi-suite.github.io/jsonapi_spec_helpers/
31+
<%- end -%>
132
JsonapiSpecHelpers::Payload.register(:<%= file_name %>) do
233
end

0 commit comments

Comments
 (0)