jsonapi_compliable 0.10.3 → 0.10.4

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
  SHA1:
3
- metadata.gz: d9efa2ffdedf8a4a1f13a45834f5a9eb4ac24889
4
- data.tar.gz: 4492499ea4a5ed17f48b7350aab498d997ce20dd
3
+ metadata.gz: f0dfed95b2e591f55607d09e2e9474d3b829c2c5
4
+ data.tar.gz: fdcb00d3692b33d53723c8fdf36e567d46b4548d
5
5
  SHA512:
6
- metadata.gz: ab2f0da8c6cdb3272dc3f24db0e73921aa0c6773996e81e61a7c5c6e4fe398800dcac6f0699564bb4a6bc25e83e4ce810f4c67a7c3e2554711df31b08b2a1000
7
- data.tar.gz: 0727d0bf57c587596c6f15e9075de5de7d2d5aeab411ef5f894700ff10d4cee58d9ee742f826be0f511ea1bab23a3cb7424d7bea8798754aa8b26a6206e9fe5c
6
+ metadata.gz: 3d5358d1bcf58341f5e77d4213a4b975390f6c97846ac21401c0d21996a97cc6c5dcaeeb4a79e0256c2bc9bb33ae2ce828157ac2bdf733cdcf08c6256d26095e
7
+ data.tar.gz: f5140772a00d7cde5f1b73a889dee660eb7d3fd895a1a710d3ff6be827ebedea47484ad115d67a15a423ebcd5f6892c962b61660c3a2afe7429e4918996fdcd7
@@ -2,41 +2,18 @@ module Jsonapi
2
2
  class ResourceGenerator < ::Rails::Generators::NamedBase
3
3
  source_root File.expand_path('../templates', __FILE__)
4
4
 
5
+ argument :attributes, type: :array, default: [], banner: "field[:type][:index] field[:type][:index]"
6
+
5
7
  class_option :'omit-comments',
6
8
  type: :boolean,
7
9
  default: false,
8
10
  aliases: ['--omit-comments', '-c'],
9
11
  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'
12
+ class_option :'actions',
13
+ type: :array,
14
+ default: nil,
15
+ aliases: ['--actions', '-a'],
16
+ desc: 'Array of controller actions to support, e.g. "index show destroy"'
40
17
 
41
18
  desc "This generator creates a resource file at app/resources, as well as corresponding controller/specs/route/etc"
42
19
  def copy_resource_file
@@ -44,18 +21,30 @@ module Jsonapi
44
21
  raise "You must define a #{class_name} model before generating the corresponding resource."
45
22
  end
46
23
 
47
- generate_controller unless omit_controller?
48
- generate_serializer unless omit_serializer?
24
+ generate_controller
25
+ generate_serializer
49
26
  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?
27
+ generate_spec_payload
28
+
29
+ if actions?('create', 'update')
30
+ generate_strong_resource
31
+ end
32
+
33
+ generate_route
34
+ generate_tests
54
35
  generate_resource
55
36
  end
56
37
 
57
38
  private
58
39
 
40
+ def actions
41
+ @options['actions'] || %w(index show create update destroy)
42
+ end
43
+
44
+ def actions?(*methods)
45
+ methods.any? { |m| actions.include?(m) }
46
+ end
47
+
59
48
  def omit_comments?
60
49
  @options['omit-comments']
61
50
  end
@@ -65,19 +54,11 @@ module Jsonapi
65
54
  template('controller.rb.erb', to)
66
55
  end
67
56
 
68
- def omit_controller?
69
- @options['omit-controller']
70
- end
71
-
72
57
  def generate_serializer
73
58
  to = File.join('app/serializers', class_path, "serializable_#{file_name}.rb")
74
59
  template('serializer.rb.erb', to)
75
60
  end
76
61
 
77
- def omit_serializer?
78
- @options['omit-serializer']
79
- end
80
-
81
62
  def generate_application_resource
82
63
  to = File.join('app/resources', class_path, "application_resource.rb")
83
64
  template('application_resource.rb.erb', to)
@@ -92,69 +73,62 @@ module Jsonapi
92
73
  template('payload.rb.erb', to)
93
74
  end
94
75
 
95
- def omit_spec_payload?
96
- @options['no-payload']
97
- end
98
-
99
76
  def generate_strong_resource
100
- code = <<-STR
101
- strong_resource :#{file_name} do
102
- # Your attributes go here, e.g.
103
- # attribute :name, :string
104
- end
77
+ code = " strong_resource :#{file_name} do\n"
78
+ attributes.each do |a|
79
+ code << " attribute :#{a.name}, :#{a.type}\n"
80
+ end
81
+ code << " end\n"
105
82
 
106
- STR
107
83
  inject_into_file 'config/initializers/strong_resources.rb', after: "StrongResources.configure do\n" do
108
84
  code
109
85
  end
110
86
  end
111
87
 
112
- def omit_strong_resource?
113
- @options['no-strong-resources']
114
- end
115
-
116
88
  def generate_route
117
- code = <<-STR
118
- resources :#{type}
119
- STR
89
+ code = " resources :#{type}"
90
+ code << ", only: [#{actions.map { |a| ":#{a}" }.join(', ')}]" if actions.length < 5
91
+ code << "\n"
120
92
  inject_into_file 'config/routes.rb', after: "scope path: '/v1' do\n" do
121
93
  code
122
94
  end
123
95
  end
124
96
 
125
- def omit_route?
126
- @options['no-route']
127
- end
128
-
129
97
  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)
98
+ if actions?('index')
99
+ to = File.join "spec/api/v1/#{file_name.pluralize}",
100
+ class_path,
101
+ "index_spec.rb"
102
+ template('index_request_spec.rb.erb', to)
103
+ end
139
104
 
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)
105
+ if actions?('show')
106
+ to = File.join "spec/api/v1/#{file_name.pluralize}",
107
+ class_path,
108
+ "show_spec.rb"
109
+ template('show_request_spec.rb.erb', to)
110
+ end
144
111
 
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)
112
+ if actions?('create')
113
+ to = File.join "spec/api/v1/#{file_name.pluralize}",
114
+ class_path,
115
+ "create_spec.rb"
116
+ template('create_request_spec.rb.erb', to)
117
+ end
149
118
 
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
119
+ if actions?('update')
120
+ to = File.join "spec/api/v1/#{file_name.pluralize}",
121
+ class_path,
122
+ "update_spec.rb"
123
+ template('update_request_spec.rb.erb', to)
124
+ end
155
125
 
156
- def omit_tests?
157
- @options['no-test']
126
+ if actions?('destroy')
127
+ to = File.join "spec/api/v1/#{file_name.pluralize}",
128
+ class_path,
129
+ "destroy_spec.rb"
130
+ template('destroy_request_spec.rb.erb', to)
131
+ end
158
132
  end
159
133
 
160
134
  def generate_resource
@@ -162,6 +136,40 @@ module Jsonapi
162
136
  template('resource.rb.erb', to)
163
137
  end
164
138
 
139
+ def jsonapi_config
140
+ File.exists?('.jsonapicfg.yml') ? YAML.load_file('.jsonapicfg.yml') : {}
141
+ end
142
+
143
+ def update_config!(attrs)
144
+ config = jsonapi_config.merge(attrs)
145
+ File.open('.jsonapicfg.yml', 'w') { |f| f.write(config.to_yaml) }
146
+ end
147
+
148
+ def prompt(header: nil, description: nil, default: nil)
149
+ say(set_color("\n#{header}", :magenta, :bold)) if header
150
+ say("\n#{description}") if description
151
+ answer = ask(set_color("\n(default: #{default}):", :magenta, :bold))
152
+ answer = default if answer.blank? && default != 'nil'
153
+ say(set_color("\nGot it!\n", :white, :bold))
154
+ answer
155
+ end
156
+
157
+ def api_namespace
158
+ @api_namespace ||= begin
159
+ ns = jsonapi_config['namespace']
160
+
161
+ if ns.blank?
162
+ ns = prompt \
163
+ header: "What is your API namespace?",
164
+ description: "This will be used as a route prefix, e.g. if you want the route '/books_api/v1/authors' your namespace would be 'books_api'",
165
+ default: 'api'
166
+ update_config!('namespace' => ns)
167
+ end
168
+
169
+ ns
170
+ end
171
+ end
172
+
165
173
  def model_klass
166
174
  class_name.safe_constantize
167
175
  end
@@ -5,12 +5,14 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
5
5
  <%- end -%>
6
6
  jsonapi resource: <%= model_klass %>Resource
7
7
 
8
+ <%- if actions?('create', 'update') -%>
8
9
  <%- unless omit_comments? -%>
9
10
  # Reference a strong resource payload defined in
10
11
  # config/initializers/strong_resources.rb
11
12
  <%- end -%>
12
13
  strong_resource :<%= file_name %>
13
-
14
+ <%- end -%>
15
+ <%- if actions?('create', 'update') -%>
14
16
  <%- unless omit_comments? -%>
15
17
  # Run strong parameter validation for these actions.
16
18
  # Invalid keys will be dropped.
@@ -19,6 +21,8 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
19
21
  <%- end -%>
20
22
  before_action :apply_strong_params, only: [:create, :update]
21
23
 
24
+ <%- end -%>
25
+ <%- if actions?('index') -%>
22
26
  <%- unless omit_comments? -%>
23
27
  # Start with a base scope and pass to render_jsonapi
24
28
  <%- end -%>
@@ -27,6 +31,8 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
27
31
  render_jsonapi(<%= file_name.pluralize %>)
28
32
  end
29
33
 
34
+ <%- end -%>
35
+ <%- if actions?('show') -%>
30
36
  <%- unless omit_comments? -%>
31
37
  # Call jsonapi_scope directly here so we can get behavior like
32
38
  # sparse fieldsets and statistics.
@@ -36,6 +42,8 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
36
42
  render_jsonapi(scope.resolve.first, scope: false)
37
43
  end
38
44
 
45
+ <%- end -%>
46
+ <%- if actions?('create') -%>
39
47
  <%- unless omit_comments? -%>
40
48
  # jsonapi_create will use the configured Resource (and adapter) to persist.
41
49
  # This will handle nested relationships as well.
@@ -51,6 +59,8 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
51
59
  end
52
60
  end
53
61
 
62
+ <%- end -%>
63
+ <%- if actions?('update') -%>
54
64
  <%- unless omit_comments? -%>
55
65
  # jsonapi_update will use the configured Resource (and adapter) to persist.
56
66
  # This will handle nested relationships as well.
@@ -66,6 +76,8 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
66
76
  end
67
77
  end
68
78
 
79
+ <%- end -%>
80
+ <%- if actions?('destroy') -%>
69
81
  <%- unless omit_comments? -%>
70
82
  # No need for any special logic here as no_content is jsonapi_compliant.
71
83
  # Customize this if you have a more complex use case.
@@ -75,5 +87,6 @@ class <%= model_klass.name.pluralize %>Controller < ApplicationController
75
87
  <%= file_name %>.destroy
76
88
  return head(:no_content)
77
89
  end
90
+ <%- end -%>
78
91
  end
79
92
  <% end -%>
@@ -15,7 +15,7 @@ RSpec.describe "<%= type %>#create", type: :request do
15
15
 
16
16
  it 'creates the resource' do
17
17
  expect {
18
- jsonapi_post "/api/v1/<%= type %>", payload
18
+ jsonapi_post "/<%= api_namespace %>/v1/<%= type %>", payload
19
19
  }.to change { <%= model_klass %>.count }.by(1)
20
20
  <%= file_name %> = <%= model_klass %>.last
21
21
 
@@ -6,7 +6,7 @@ RSpec.describe "<%= type %>#destroy", type: :request do
6
6
 
7
7
  it 'updates the resource' do
8
8
  expect {
9
- delete "/api/v1/<%= type %>/#{<%= file_name %>.id}"
9
+ delete "/<%= api_namespace %>/v1/<%= type %>/#{<%= file_name %>.id}"
10
10
  }.to change { <%= model_klass %>.count }.by(-1)
11
11
 
12
12
  expect(response.status).to eq(204)
@@ -6,7 +6,7 @@ RSpec.describe "<%= file_name.pluralize %>#index", type: :request do
6
6
  let!(:<%= file_name %>2) { create(:<%= file_name %>) }
7
7
 
8
8
  it 'serializes the list correctly' do
9
- get "/api/v1/<%= file_name.pluralize %>"
9
+ get "/<%= api_namespace %>/v1/<%= file_name.pluralize %>"
10
10
 
11
11
  expect(json_ids(true)).to match_array([<%= file_name %>1.id, <%= file_name %>2.id])
12
12
  assert_payload(:<%= file_name %>, <%= file_name %>1, json_items[0])
@@ -30,4 +30,8 @@
30
30
  # For more information, see https://jsonapi-suite.github.io/jsonapi_spec_helpers/
31
31
  <%- end -%>
32
32
  JsonapiSpecHelpers::Payload.register(:<%= file_name %>) do
33
+ <%- attributes.each do |a| -%>
34
+ <%- type = a.type == :boolean ? [TrueClass, FalseClass] : a.type.to_s.classify -%>
35
+ key(:<%= a.name %>, <%= type %>)
36
+ <%- end -%>
33
37
  end
@@ -18,5 +18,8 @@ class Serializable<%= class_name %> < JSONAPI::Serializable::Resource
18
18
  # @object.name.upcase
19
19
  # end
20
20
  <%- end -%>
21
+ <%- attributes.each do |a| -%>
22
+ attribute :<%= a.name %>
23
+ <%- end -%>
21
24
  end
22
25
  <% end -%>
@@ -5,7 +5,7 @@ RSpec.describe "<%= file_name.pluralize %>#show", type: :request do
5
5
  let!(:<%= file_name %>) { create(:<%= file_name %>) }
6
6
 
7
7
  it 'serializes the resource correctly' do
8
- get "/api/v1/<%= file_name.pluralize %>/#{<%= file_name %>.id}"
8
+ get "/<%= api_namespace %>/v1/<%= file_name.pluralize %>/#{<%= file_name %>.id}"
9
9
 
10
10
  assert_payload(:<%= file_name %>, <%= file_name %>, json_item)
11
11
  end
@@ -19,7 +19,7 @@ RSpec.describe "<%= type %>#update", type: :request do
19
19
  # Replace 'xit' with 'it' after adding attributes
20
20
  xit 'updates the resource' do
21
21
  expect {
22
- jsonapi_put "/api/v1/<%= type %>/#{<%= file_name %>.id}", payload
22
+ jsonapi_put "/<%= api_namespace %>/v1/<%= type %>/#{<%= file_name %>.id}", payload
23
23
  }.to change { <%= file_name %>.reload.attributes }
24
24
  assert_payload(:<%= file_name %>, <%= file_name %>, json_item)
25
25
 
@@ -1,3 +1,3 @@
1
1
  module JsonapiCompliable
2
- VERSION = "0.10.3"
2
+ VERSION = "0.10.4"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jsonapi_compliable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.10.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lee Richmond
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: exe
11
11
  cert_chain: []
12
- date: 2017-10-17 00:00:00.000000000 Z
12
+ date: 2017-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: jsonapi-serializable