rails-api_controller_generator 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- 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: []
|