rails-api_controller_generator 0.8.0
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 +7 -0
- data/lib/generators/api_controller/api_controller_generator.rb +28 -0
- data/lib/generators/api_controller/install/install_generator.rb +17 -0
- data/lib/generators/api_controller/install/templates/api_helper.rb +9 -0
- data/lib/generators/api_controller/install/templates/base_controller.rb +55 -0
- data/lib/generators/api_controller/templates/controller.rb +60 -0
- data/lib/generators/rspec/api_controller_generator.rb +14 -0
- data/lib/generators/rspec/templates/api_spec.rb +127 -0
- metadata +51 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: 011a416363c1bd330b5facd8c93cffd4583914f2
|
|
4
|
+
data.tar.gz: eed63327b3d82db1311d07d3ed573e1b9a295d9a
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 4a74ca1e98a8f636b5230ba9a12def0931894e4f58fb2426d3be1976f7076b7c675dfa556892593e24340d1b1216f424d6753c98ddbf5f099d45a53cb60875df
|
|
7
|
+
data.tar.gz: 550fe850bca92b88984aa1304b878c3c722f511038a3a7bc0ed9bdde65dbf81ca44b7e9f713ea4afa609652ec8f5732064d7bfb028f40904a4f9a1c788779545
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require 'rails/generators/resource_helpers'
|
|
2
|
+
|
|
3
|
+
class ApiControllerGenerator < Rails::Generators::NamedBase
|
|
4
|
+
source_root File.expand_path('../templates', __FILE__)
|
|
5
|
+
|
|
6
|
+
include ::Rails::Generators::ResourceHelpers
|
|
7
|
+
|
|
8
|
+
check_class_collision suffix: "Controller"
|
|
9
|
+
|
|
10
|
+
class_option :orm, banner: "NAME", type: :string, required: true,
|
|
11
|
+
desc: "ORM to generate the controller for"
|
|
12
|
+
|
|
13
|
+
def create_controller_file
|
|
14
|
+
template "controller.rb", File.join('app/controllers/api', controller_class_path, "#{controller_file_name}_controller.rb")
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def add_routes_entry
|
|
18
|
+
insert_into_file "config/routes.rb", :after => "Rails.application.routes.draw do\n" do
|
|
19
|
+
<<CODE
|
|
20
|
+
namespace :api do
|
|
21
|
+
resources :#{controller_file_name}
|
|
22
|
+
end\n
|
|
23
|
+
CODE
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
hook_for :test_framework
|
|
28
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module ApiController
|
|
2
|
+
module Generators
|
|
3
|
+
class InstallGenerator < ::Rails::Generators::Base
|
|
4
|
+
desc 'Copies the required files for ApiControllerGenerator'
|
|
5
|
+
source_root ::File.expand_path('../templates', __FILE__)
|
|
6
|
+
|
|
7
|
+
def copy_base_controller
|
|
8
|
+
copy_file "base_controller.rb", "app/controllers/api/base_controller.rb"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def copy_rspec_helper_file
|
|
12
|
+
empty_directory 'spec/support'
|
|
13
|
+
copy_file "api_helper.rb", "spec/support/api_helper.rb"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
class Api::BaseController < ApplicationController
|
|
2
|
+
protected
|
|
3
|
+
def send_success(data, status=200, options={})
|
|
4
|
+
obj = {json: data, status: status}
|
|
5
|
+
obj = obj.merge options
|
|
6
|
+
render obj
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def send_error(data, status=422)
|
|
10
|
+
logger.error data.to_json
|
|
11
|
+
render json: data, status: status
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def send_no_content(status=204)
|
|
15
|
+
head status
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def send_not_found(message=nil)
|
|
19
|
+
if message.nil?
|
|
20
|
+
head 404, "content_type" => 'text/plain'
|
|
21
|
+
else
|
|
22
|
+
render json: {message: message}, status: 404
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def send_forbidden(message=nil)
|
|
27
|
+
if message.nil?
|
|
28
|
+
head 403, "content_type" => 'text/plain'
|
|
29
|
+
else
|
|
30
|
+
render json: {message: message}, status: 403
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def send_validation_errors(errors, message="Validation failed")
|
|
35
|
+
if errors.is_a? ActiveModel::Errors
|
|
36
|
+
all_error_objects = []
|
|
37
|
+
errors.keys.each do |field|
|
|
38
|
+
err_obj = {}
|
|
39
|
+
err_obj[:field] = field
|
|
40
|
+
err_obj[:message] = errors[field].join(", ")
|
|
41
|
+
all_error_objects << err_obj
|
|
42
|
+
end
|
|
43
|
+
else
|
|
44
|
+
all_error_objects = errors
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
logger.error all_error_objects.to_json
|
|
48
|
+
|
|
49
|
+
render json: {message: message, errors: all_error_objects}, status: 422
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def default_serializer_options
|
|
53
|
+
{root: false}
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<% module_namespacing do -%>
|
|
2
|
+
class Api::<%= controller_class_name %>Controller < Api::BaseController
|
|
3
|
+
# list
|
|
4
|
+
def index
|
|
5
|
+
send_success(find_all)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# get
|
|
9
|
+
def show
|
|
10
|
+
send_success(find)
|
|
11
|
+
rescue ActiveRecord::RecordNotFound
|
|
12
|
+
send_not_found
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# insert
|
|
16
|
+
def create
|
|
17
|
+
<%= singular_table_name %> = <%= orm_class.build(class_name, "#{singular_table_name}_params") %>
|
|
18
|
+
<%= singular_table_name %>.save!
|
|
19
|
+
send_success(<%= singular_table_name %>, 201)
|
|
20
|
+
rescue ActiveRecord::RecordInvalid
|
|
21
|
+
send_error(<%= singular_table_name %>.errors)
|
|
22
|
+
rescue ActiveRecord::RecordNotFound => e
|
|
23
|
+
send_error(e.message)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# patch
|
|
27
|
+
def update
|
|
28
|
+
<%= singular_table_name %> = find
|
|
29
|
+
<%= singular_table_name %>.update!(<%= singular_table_name %>_params)
|
|
30
|
+
send_success(<%= singular_table_name %>)
|
|
31
|
+
rescue ActiveRecord::RecordNotFound
|
|
32
|
+
send_not_found
|
|
33
|
+
rescue ActiveRecord::RecordInvalid
|
|
34
|
+
send_error(<%= singular_table_name %>.errors)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# delete
|
|
38
|
+
def destroy
|
|
39
|
+
<%= singular_table_name %> = find
|
|
40
|
+
<%= singular_table_name %>.destroy
|
|
41
|
+
send_no_content
|
|
42
|
+
rescue ActiveRecord::RecordNotFound
|
|
43
|
+
send_not_found
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
private
|
|
47
|
+
def <%= "#{singular_table_name}_params" %>
|
|
48
|
+
params.require(:<%= singular_table_name %>).permit(
|
|
49
|
+
<%= (class_name.constantize.column_names - ['id', 'created_at', 'updated_at']).map { |name| ":#{name}" }.join(",\n\t\t\t") %>)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def find_all
|
|
53
|
+
<%= orm_class.all(class_name) %>
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def find
|
|
57
|
+
<%= orm_class.find(class_name, "params[:id]") %>
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
<% end -%>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module Rspec
|
|
2
|
+
module Generators
|
|
3
|
+
class ApiControllerGenerator < Rails::Generators::NamedBase
|
|
4
|
+
source_root File.expand_path("../templates", __FILE__)
|
|
5
|
+
|
|
6
|
+
desc "Generates an API controller spec in spec/api"
|
|
7
|
+
|
|
8
|
+
def generate_spec
|
|
9
|
+
empty_directory 'spec/api'
|
|
10
|
+
template "api_spec.rb", "spec/api/#{file_name.pluralize}_api_spec.rb"
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
require 'rails_helper'
|
|
2
|
+
|
|
3
|
+
RSpec.describe "<%= class_name.pluralize %> API", type: :request do
|
|
4
|
+
before :each do
|
|
5
|
+
host! "example.com"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
xcontext "list" do
|
|
9
|
+
it 'returns the list of all records' do
|
|
10
|
+
create_<%= file_name %>
|
|
11
|
+
get endpoint_url
|
|
12
|
+
|
|
13
|
+
result = json(response.body)
|
|
14
|
+
expect(response.status).to eq(200)
|
|
15
|
+
expect(result.count).to eq(1)
|
|
16
|
+
# TODO: assert returned data
|
|
17
|
+
expect(result.first[:attribute_1]).to eq('value_1')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "returns an empty array if no records are found" do
|
|
21
|
+
get endpoint_url
|
|
22
|
+
|
|
23
|
+
result = json(response.body)
|
|
24
|
+
expect(response.status).to eq(200)
|
|
25
|
+
expect(result).to eq([])
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
xcontext "get" do
|
|
30
|
+
it 'returns a record by id' do
|
|
31
|
+
# TODO: persist a record
|
|
32
|
+
<%= file_name %> = create_<%= file_name %>
|
|
33
|
+
get endpoint_url_with_id(<%= file_name %>.id)
|
|
34
|
+
|
|
35
|
+
result = json(response.body)
|
|
36
|
+
expect(response.status).to eq(200)
|
|
37
|
+
# TODO: assert returned data
|
|
38
|
+
expect(result[:attribute_1]).to eq('value_1')
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it "returns 404 response if record not found" do
|
|
42
|
+
get endpoint_url_with_id(123)
|
|
43
|
+
|
|
44
|
+
expect(response.status).to eq(404)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
xcontext "insert" do
|
|
49
|
+
it "returns 201 response if successful" do
|
|
50
|
+
# TODO: set data for the request
|
|
51
|
+
data = { attribute_1: 'value_1' }
|
|
52
|
+
post endpoint_url, params: { <%= file_name %>: data }
|
|
53
|
+
|
|
54
|
+
result = json(response.body)
|
|
55
|
+
expect(response.status).to eq(201)
|
|
56
|
+
expect(result[:id]).to_not be_nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
it "returns 422 response if failed to create" do
|
|
60
|
+
# TODO: set some invalid data for the request
|
|
61
|
+
data = {attribute_1: ''}
|
|
62
|
+
post endpoint_url, params: { <%= file_name %>: data }
|
|
63
|
+
|
|
64
|
+
result = json(response.body)
|
|
65
|
+
expect(result).to_not be_empty
|
|
66
|
+
expect(response.status).to eq(422)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
xcontext "patch" do
|
|
71
|
+
it "returns 200 response if successful" do
|
|
72
|
+
<%= file_name %> = create_<%= file_name %>
|
|
73
|
+
# TODO: set updated data for the request
|
|
74
|
+
data = {attribute_1: 'updated_value_1'}
|
|
75
|
+
patch endpoint_url_with_id(<%= file_name %>.id), params: { <%= file_name %>: data }
|
|
76
|
+
|
|
77
|
+
expect(response.status).to eq(200)
|
|
78
|
+
# TODO: assert updated data
|
|
79
|
+
expect(<%= file_name %>.reload.attribute_1).to eq('updated_value_1')
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
it "returns 422 response if failed to update" do
|
|
83
|
+
<%= file_name %> = create_<%= file_name %>
|
|
84
|
+
# TODO: set some invalid data for the request
|
|
85
|
+
data = {attribute_1: ''}
|
|
86
|
+
patch endpoint_url_with_id(<%= file_name %>.id), params: { <%= file_name %>: data }
|
|
87
|
+
|
|
88
|
+
expect(response.status).to eq(422)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it "returns 404 response if record not found" do
|
|
92
|
+
patch endpoint_url_with_id(123), params: { <%= file_name %>: {} }
|
|
93
|
+
expect(response.status).to eq(404)
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
xcontext "delete" do
|
|
98
|
+
it "returns 204 response if successful" do
|
|
99
|
+
<%= file_name %> = create_<%= file_name %>
|
|
100
|
+
delete endpoint_url_with_id(<%= file_name %>.id)
|
|
101
|
+
|
|
102
|
+
expect(response.status).to eq(204)
|
|
103
|
+
all_<%= file_name.pluralize %> = <%= class_name %>.all
|
|
104
|
+
expect(all_<%= file_name.pluralize %>.count).to eq(0)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
it "returns 404 response if record not found" do
|
|
108
|
+
delete endpoint_url_with_id(123)
|
|
109
|
+
expect(response.status).to eq(404)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
private
|
|
114
|
+
def create_<%= file_name %>
|
|
115
|
+
raise NotImplementedError
|
|
116
|
+
# TODO:
|
|
117
|
+
# <%= class_name %>.create!(attribute_1: 'value_1')
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def endpoint_url
|
|
121
|
+
"/api/<%= file_name.pluralize %>"
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def endpoint_url_with_id(id)
|
|
125
|
+
"/api/<%= file_name.pluralize %>/#{id}"
|
|
126
|
+
end
|
|
127
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rails-api_controller_generator
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.8.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Chanaka Sandaruwan
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: bin
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2016-09-07 00:00:00.000000000 Z
|
|
12
|
+
dependencies: []
|
|
13
|
+
description: Generates API controllers with endpoints for basic crud operations for
|
|
14
|
+
a model.
|
|
15
|
+
email: chanakasan@gmail.com
|
|
16
|
+
executables: []
|
|
17
|
+
extensions: []
|
|
18
|
+
extra_rdoc_files: []
|
|
19
|
+
files:
|
|
20
|
+
- lib/generators/api_controller/api_controller_generator.rb
|
|
21
|
+
- lib/generators/api_controller/install/install_generator.rb
|
|
22
|
+
- lib/generators/api_controller/install/templates/api_helper.rb
|
|
23
|
+
- lib/generators/api_controller/install/templates/base_controller.rb
|
|
24
|
+
- lib/generators/api_controller/templates/controller.rb
|
|
25
|
+
- lib/generators/rspec/api_controller_generator.rb
|
|
26
|
+
- lib/generators/rspec/templates/api_spec.rb
|
|
27
|
+
homepage: https://github.com/chanakasan/rails-api_controller_generator
|
|
28
|
+
licenses:
|
|
29
|
+
- Apache License, Version 2.0
|
|
30
|
+
metadata: {}
|
|
31
|
+
post_install_message:
|
|
32
|
+
rdoc_options: []
|
|
33
|
+
require_paths:
|
|
34
|
+
- lib
|
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - ">="
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: 1.9.3
|
|
40
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
41
|
+
requirements:
|
|
42
|
+
- - ">="
|
|
43
|
+
- !ruby/object:Gem::Version
|
|
44
|
+
version: '0'
|
|
45
|
+
requirements: []
|
|
46
|
+
rubyforge_project:
|
|
47
|
+
rubygems_version: 2.2.3
|
|
48
|
+
signing_key:
|
|
49
|
+
specification_version: 4
|
|
50
|
+
summary: Generates API controllers with endpoints for basic crud operations.
|
|
51
|
+
test_files: []
|